Reputation: 5649
I am working on a Ruby project that outputs text where I want to allow other code to change part of the wrapper. Below is a simplified example:
yield
will make the project generate the inner contents.However, I get a very strange error when attempting to run the following code:
def wrapper(&block)
puts "begin outer wrapper"
block.call do
puts "inner content"
end
puts "end outer wrapper"
end
wrapper do
puts "begin inner wrapper"
yield
puts "end inner wrapper"
end
I would expect the following output:
begin outer wrapper
begin inner wrapper
inner content
end inner wrapper
end outer wrapper
This does not happen. Instead, Ruby throws the following error: LocalJumpError: no block given (yield)
What is going wrong?
EDIT: Based on @JörgWMittag's answer, this is a variant that does work:
def wrapper(&block)
puts "begin outer wrapper"
block.call do
puts "inner content"
end
puts "end outer wrapper"
end
wrapper do |&inner_block|
puts "begin inner wrapper"
inner_block.call
puts "end inner wrapper"
end
Basically, yield
and Proc#call()
are very different beasts after all.
Upvotes: 2
Views: 242
Reputation: 369633
What is going wrong?
yield
transfers control to the block that was passed to the method in whose definition the yield
appears. In your case, the yield
doesn't appear in a method definition, ergo, there is nowhere to yield
to.
Upvotes: 4