block syntax difference causes "LocalJumpError: no block given (yield)"

20,154

Solution 1

The parser recognizes this

p test do
  1
end

as this

p(test) do
  1
end

The block is passed to p, not test. Therefore, yield can't yield and raises that error.

Solution 2

do and {} to denote blocks attached to methods are not completely interchangeable.

p test do
  1
end

Precedence is screwing with you. This is actually this:

p(test()) do
  1
end

So the block is getting passed to p, not test.

{} has higher precedence than do, and so binds more tightly to the syntactically closer method. This is also true for other ruby keywords that have symbolic equivalents, such as and/&& and or/||, which is why the symbols are usually recommended over the words.

Share:
20,154
Mindey I.
Author by

Mindey I.

Co-founder and CEO of https://coinbase.com Personal blog at http://brianarmstrong.org Lover of software engineering.

Updated on February 25, 2020

Comments

  • Mindey I.
    Mindey I. about 4 years

    Saw a strange case come up, trying to figure out what is happening here:

    > 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)