Поведение ключевого слова return в блоке ruby - PullRequest
3 голосов
/ 20 апреля 2011

Может ли кто-нибудь объяснить поведение следующих

def iterate
  return yield
  return "end of iterate"
end

def test_iterate
  assert_equal( "end of iterate",  iterate { return "end of block" } )
  assert_equal( "end of block",  iterate { "end of block" } )
end

Я понимаю, что Procs (то есть блоки) должны возвращаться в пределах области, которую они называют.(В отличие от лямбда-выражений) Не следует ли обоим вызовам в тестах возвращать «конец блока»?

Этот тест проходит на 'ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0] '(OSX 10.6.7)

1 Ответ

4 голосов
/ 23 апреля 2011

Ключевое слово return возвращает лексический метод. То есть * test_iterate *.

Чтобы вернуть определенное значение из блока динамически в определенной области, вместо этого следует использовать ключевое слово break .

В вашем случае:

iterate { break("end of block") }

Тест не пройден. потому что второй оператор возврата метода итерации никогда не запустится.

Предполагаемая семантика должна выполняться с использованием исключений:

def iterate
  return yield
  rescue :exception
    return "end of iterate"
end

def test_iterate
  assert_equal( "end of iterate",  iterate { raise :exception } )
  assert_equal( "end of block",  iterate { "end of block" } )
end
...