David A. Black wrote:
> Hi --
> 
> On Fri, 16 Nov 2007, Michael Neumann wrote:
> 
>> If you use Ruby 1.9, you can use Object#tap:
>>
>>  "I am a 20MB string".tap {|i| i.downcase!}.split(/\s+/).tap {|i|
>>  i.reject!{|s|s.length>20}
>>
>> But why not split it in multiple lines? I think it will become more 
>> readable than using #tap:
>>
>>  str = "..."
>>  str.downcase!
>>  arr = str.split(..)
>>  arr.reject!{...}
> 
> It's interesting that almost every example of #tap ends up saying that
> it's probably better not to use it, for one reason or another (usually
> readability; sometimes the dangers of mixing bang and non-bang
> methods).
> 
> It makes me wonder whether the main effect of #tap is going to be a
> lot of warnings that it isn't a best practice. Or are there examples
> that *don't* look worse than the alternatives?
> 
> 
> David
> 

The use case that occurs to me (I'm not sure that it will convince you 
though) is to "tap" into an already existing method chain.  The 
existence of tap shouldn't cause the creation of longer chains, but if 
someone is writing in that style, it is nice to be able to insert 
things, like debugging or logging output, without breaking the chain up.

Here's the (extreme) example from my book:

chars = "hello world".tap {|x| puts "original object: #{x.inspect}"}
   .each_char         .tap {|x| puts "each_char returns: #{x.inspect}"}
   .to_a              .tap {|x| puts "to_a returns: #{x.inspect}"}
   .map {|c| c.succ } .tap {|x| puts "map returns: #{x.inspect}" }
   .sort              .tap {|x| puts "sort returns: #{x.inspect}"}

The method chain goes vertically down the page, relying the new 
fluent-programming syntax Matz enabled, and the taps stretch out 
horizontally.

	David