Ответ 1
Парсер признает это
p test do
1
end
как это
(p test) do
1
end
Блок передается в p
, а не в test
. Следовательно, yield
не может дать результат и вызывает эту ошибку.
Увидел странный случай, пытаясь понять, что здесь происходит:
> def test
> p yield
> end
=> nil
> test { 1 }
1
=> 1
> p test { 1 }
1
1
=> 1
> p test do
> 1
> end
LocalJumpError: no block given (yield)
Парсер признает это
p test do
1
end
как это
(p test) do
1
end
Блок передается в p
, а не в test
. Следовательно, yield
не может дать результат и вызывает эту ошибку.
do
и {}
для обозначения блоков, прикрепленных к методам, не являются полностью взаимозаменяемыми.
p test do
1
end
Приоритет прикручивает вас. На самом деле это:
p(test()) do
1
end
Итак, блок переходит к p
, а не test
.
{}
имеет более высокий приоритет, чем do
, и поэтому более тесно привязывается к синтаксически более близкому методу. Это справедливо и для других рубиновых ключевых слов с символическими эквивалентами, таких как and
/&&
и or
/||
, поэтому символы обычно рекомендуются по словам.