From: Sam McCall Date: 2004-08-12T23:46:12+09:00 Subject: Re: [proto-rcr] Blocks: default arguments and method signatures David A. Black wrote: >>That example would become: >> >>def transform_values(array) &block={|val,newval| out<< newval} > > I can definitely see the point of the default assignment, but I > think you're changing too much here by putting it outside the > arglist. &block is a special argument, I know, but it's still > part of the list. That was a typo :-# > I also don't like the forward reference to a local variable here > (out). When you get to this: > >> out=[] unless block_given? > > it really feels a bit convoluted. Yes, as I posted above, I tested the equivalent code but made a mistake. I withdraw this part :) >> array.each { |value| >> #calculations... >> yield value,newvalue > I think block.call(value,newvalue) would be clearer here, since yield > really means that the business is being done by switching control to a > block provided in association with the method call. I understand that > you're sort of retro-fitting your default block to play that role, but > I still think it's better to save yield for the traditional yield > scenario. Or the block could be anonymous, which might be clear enough... > You're not returning 'out'? Oops, I forgot. I really couldn't test this one! > And if you are, are you sure you want > the return value to be nil if a block was given? That was the intention in this example. (Recently I've been using large data sets, one huge array is enough!) > Just for completeness, here's a present-day version that returns the > original array if a block is given, and otherwise returns the > accumulated transformations: > > def transform_values(array,&block) > res = if block then array else [] end > block ||= lambda {|val,newval| res << newval } > > array.each do |value| > newvalue = value * 10 > block.call(value, newvalue) > end > > return res > end Nice, I like the res trick... For that matter: def transform_values(array,&block) array.map{|value| newvalue=value*10 block ? begin block[value,newvalue]; value end : newvalue } end Thanks, Sam