I am using ruby 1.8.7.
p = lambda { return 10;}
def lab(block)
puts 'before'
puts block.call
puts 'after'
end
lab p
Above code output is
before
10
after
I refactored same code into this
def lab(&block)
puts 'before'
puts block.call
puts 'after'
end
lab { return 10; }
Now I am getting LocalJumpError: unexpected return.
To me both the code are doing same thing. Yes in the first case I am passing a proc and in the second case I am passing a block. But &block converts that block into proc. So proc.call should behave same.
And yes I have seen this post Using 'return' in a Ruby block
When you pass in the block with &, you’re converting it to a proc. The important point is that a proc and a lambda are different (lambda is actually a subclass of proc), specifically in how they deal with return.
So your refactored code is actually the equivalent of:
which also generates a LocalJumpError.
Here’s why: A proc’s return returns from its lexical scope, but a lambda returns to its execution scope. So whereas the lambda returns to
lab, the proc passed into it returns to the outer scope in which it was declared. The local jump error means it has nowhere to go, because there’s no enclosing function.The Ruby Programming Language says it best:
You just have to keep track of what you’re using where. As others have suggested, all you need to do is drop the
returnfrom your block, and things will work as intended.