Those semantics would be more consistent with yield and blk.call, and
generally I applaud anything which improves consistency:
def foo
yield 1
end
foo {|a,b| p a,b} # prints 1, nil
def bar(&blk)
blk.call(1)
end
bar {|a,b| p a,b} # prints 1, nil
However I tend towards the other position: that both the above examples
should raise an "incorrect number of arguments" exception. It tends to trap
errors sooner, rather than later. But I don't feel too strongly about which
way it's done; I feel much more strongly that it should be consistent!
I quite like your suggestion of &blk=nil though. At the moment in Ruby the
presence/absence of a block makes no difference, until you try to 'yield'
when no block is given. In particular, you can pass a block to a method
which doesn't expect one; I've been caught by that before!
So in an ideal world I'd have
def foo(a,b) # block forbidden, raise exception if you pass one
def foo(a,b,&c) # block required, raise exception if it's missing
def foo(a,b,&c=nil) # block optional
That syntax would also allow a 'default block':
def foo(a,b,&c=proc{|x| $stderr.puts x})
Regards,
Brian.
···
On Sun, Oct 03, 2004 at 12:29:39PM +0900, trans. (T. Onoma) wrote:
But since then, I've completely flipped positions, and more in concert with
the ideas of duck-typing, I wish all arguments worked like &block. e.g.
def foo(a, b)
"#{a}#{b}"
end
foo(1) #=> "1"
Just as block is nil in the above, so would b here. Likewise:
foo(1,2,3) #=> "12"
and 3 would be ignored.