It says "Invokes the method identified by symbol, passing it any arguments
specified." A block is an argument...
Correct, a block IS an argument, but of a rather unusual type in that
it may or may not be explicit in the definition of a method that uses
it.
HOWEVER, if a method (call it method bar or baz) passes any block it
receives on to yet another method (call it method foo), it is best
that the documents include this fact.
AN EXAMPLE:
## Method foo() may or may not be given a block...
def foo(*args)
puts "foo(#{args.inspect}) called with" + (block_given? ? '' :
'out') + " a block included."
yield *args if block_given?
end
## Method bar() does NOT explicitly capture block arguments
## and thus does NOT pass any given block on to foo():
def bar(*args)
puts "bar(#{args.inspect}) called with" + (block_given? ? '' :
'out') + " a block included."
foo(*args)
end
## Method baz() DOES explicitly capture block arguments
## and DOES pass any given block on to foo():
def baz(*args, &block)
puts "baz(#{args.inspect}) called with" + (block_given? ? '' :
'out') + " a block included."
foo(*args, &block)
end
bar("some", :args => "for bar", :without => "a block")
puts
bar("some", :args => "for bar", :with => "a block") { |*a| puts "block
passed to bar(): #{a.inspect}" }
puts "--"
baz("some", :args => "for baz", :without => "a block")
puts
baz("some", :args => "for baz", :with => "a block") { |*a| puts "block
passed to baz(): #{a.inspect}" }
SAMPLE OUTPUT FROM ABOVE EXAMPLE:
bar(["some", {:args=>"for bar", :without=>"a block"}]) called without
a block included.
foo(["some", {:args=>"for bar", :without=>"a block"}]) called without
a block included.
bar(["some", {:args=>"for bar", :with=>"a block"}]) called with a
block included.
foo(["some", {:args=>"for bar", :with=>"a block"}]) called without a
block included.
--
baz(["some", {:args=>"for baz", :without=>"a block"}]) called without
a block included.
foo(["some", {:args=>"for baz", :without=>"a block"}]) called without
a block included.
baz(["some", {:args=>"for baz", :with=>"a block"}]) called with a
block included.
foo(["some", {:args=>"for baz", :with=>"a block"}]) called with a
block included.
block passed to baz(): ["some", {:args=>"for baz", :with=>"a block"}]
THINGS TO NOTE FROM THE EXAMPLE:
* Notice that even though bar() uses the splat to capture and pass
through all supplied arguments, because it does NOT explicitly include
a &block argument, it does NOT automatically pass through any provided
block.=
* Note that baz() DOES explicitly include a &block argument and
explicitly passes it through.
When I read documents and see a method that does NOT explicitly
mention a block, I assume that it will NOT pass any supplied block on
to yet another method.
Hence, I expect that the send() documentation really should mention
that any block passed to it IS passed through to the method specified
as the first argument to send().
Maybe I'm eccentric, but I prefer that documentation for a method
which uses a block, either directly or by passing it through to
another method, whether the block is explicit or implicit in the
method definition, to clearly document what the block is used for or
what is done with it.
Aaron out.