You are confusing Ruby's yield statement with Enumerator::Yielder's yield method and Proc's yield method. They may be spelled the same but they are completely different.
Statement
The yield statement has no receiver. Inside a method it means "Run the block right now". An error occurs if no block is attached. It is not always given an argument, because sometimes you just want to run the block.
def foo
yield :bar
end
foo # LocalJumpError
foo { |x| puts x } # bar
Enumerator::Yielder
For a yielder, yield
is almost always given an argument. That's because it means the same as <<
which is "The next time someone calls next
on me, give them this value".
Enumerator.new { |yielder| yielder.yield 3 }.next # 3
Enumerator.new { |yielder| yielder << 3 }.next # same thing
I think it's a good idea to use <<
to avoid confusion with the yield statement.
Proc
Procs and lambdas are basically functions. yield
here means the same thing as call
, which "Just call the function". You can give it an argument or not, depending on how the proc was defined. Nothing fancy here.
proc { |x| puts x }.yield(:bar) # bar
proc { |x| puts x }.call(:bar) # same thing as previous line
I think it's a good idea to use call
to avoid confusion with the yield statement.