I am comfortable with the following:
def some_def(foo, &block)
puts "block utilized below"
block.call(foo)
end
def some_other_def(bar)
puts "using yield below"
yield bar
puts "and back into the method"
end
So I have learned to keep blocks (and procs) separate from the yield keyword.
However, I ran into the following code:
# ./open_file.rb
class File
def self.open(name, mode, &block)
file = new(name, mode)
return file unless block_given?
yield(file)
ensure
file.close
end
end
It seems the parameter &block does not matter when I implement execute this code in irb:
irb -r ./file.open.rb
and do something like:
File.open('foo.txt','r') {|f| puts f}
Is &block rendered optional by block_given? in:
return file unless block_given?
Generally, you only use the
&blockargument if you need to pass the block to another method such as in this made up example:or this real version of
Enumerable#sumfrom Rails:In either case, the block that the method is called with is used with another method call so you need a way to refer to the block (i.e. a name).
So
block_given?/yieldand&blockserve different purposes. Being able to callblock_given?doesn't make&blockredundant and, as in the#sumimplementation above, they can even be used together.