Почему LocalJumpError?

Возможный дубликат:
Использование return в Ruby блокировать

Я новичок в Ruby и был удивлен, что этот фрагмент raise a LocalJumpError, когда блок return:

$bail_if = proc { |condition|
  if condition
    puts 'the condition is true'
    return
  else
    puts 'the condition is false'
  end
}

def method some_condition
  $bail_if[some_condition]
end

method true

Если бы я определил bail_if как локальную переменную в def method, тогда проблем не было бы. Почему это?


person sivabudh    schedule 01.12.2011    source источник
comment
У меня работает на рубине 1.8.7. Вы используете рубин 1.9?   -  person Alex Wayne    schedule 02.12.2011
comment
Ой, забыл упомянуть, что я использую 1.9.2p290. Спасибо!   -  person sivabudh    schedule 02.12.2011
comment
Вы спрашиваете об этом, потому что хотите, чтобы method возвращалось, если some_condition истинно, а в противном случае продолжалось выполнение остальной части метода method? Кстати, method не идеальное имя, потому что уже есть метод, называемый методом   -  person Andrew Grimm    schedule 02.12.2011
comment
@Squeegy: Это потому, что proc ведет себя по-разному в 1.8 и 1.9 - в 1.8 он возвращает лямбда, а в 1.9 возвращает proc. См. пункт 2 здесь.   -  person Andrew Grimm    schedule 02.12.2011
comment
@AndrewGrimm, да, я спрашиваю об этом, потому что я хочу, чтобы method возвращалось, если some_condition верно, но в противном случае продолжалось выполнение остальных method.   -  person sivabudh    schedule 02.12.2011


Ответы (2)


Измените свой proc { |condition| на lambda { |condition|. proc-object имеет блочную семантику, тогда как лямбда-объект имеет семантику метода. Поскольку объект proc подобен блоку, когда вы вызываете proc, выполняющий оператор return, он пытается вернуться из метода, содержащего блок, который был преобразован в proc. У вас нет такого метода в вашем первом случае, и, как следствие, вы получаете LocalJumpError. Когда вы определяете свой proc как локальную переменную в своем методе, все работает нормально.

person WarHog    schedule 01.12.2011
comment
Он не выдаст исключение, но я не думаю, что он будет делать то, что хочет ОП. - person Andrew Grimm; 02.12.2011

Вы не return из процедуры (также известной как блок) в ruby ​​1.9. Избавление от этого явного return, кажется, исправляет это. Но этот return все равно здесь совершенно бесполезен.

Или, если вам нужен явный возврат, используйте вместо этого lambda, как предлагает @WarHog.

person Alex Wayne    schedule 01.12.2011