From: Brian Candler Date: 2004-10-04T17:06:08+09:00 Subject: Re: Too Many Ways? 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. 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.