From: spooq Date: 2006-11-20T19:48:23+09:00 Subject: Re: #returning and #tap On 11/20/06, spooq wrote: > On 11/17/06, dblack@wobblini.net wrote: > > > I'm afraid I don't follow. Can you show how you'd write this in the > > ways you've described? Since you can't reliably chain gsub! with > > anything else, I'm not sure how it would play out. > > What I mean is to chain with gsub instead, or to make it obvious that > you are changing the original by using separate lines. > > In effect, you want to do this... > > foo.gsub!.bar > > I'm saying, if you want functional style chaining, obey the unwritten > rules and don't have side-effects in the chain. > > foo.gsub.bar > > If you want to modify the original, use traditional imperative style > with side-effects. > > foo.gsub! > foo.bar > > Mixing the two styles is just going to cause confusion in long chains. > Think of it this way... do you care about foo, or about the return > value of foo.gsub ? By modifying in a chain, you're saying you care > about both, even though they have the same value. Not a problem, you > say? Then think about this case.... > > foo.gsub!.gsub.gsub! > > I feel sorry for the maintenance programmer already. > > I think I need to make this more explicit for it to be clear. Only the gsub!'s need to be wrapped in tap()'s... the gsub must be directly inline because of the need to use it's return value. Wrapping it is equivalent to deleting it from the chain. My point is really about it not being clear when foo itself is being passed along, as opposed to something derived from applying a function to foo. Does that make more sense? I get the feeling I'm not explaining myself very well. foo.tap { gsub! }.gsub.tap { gsub! } should be written as foo.gsub! foo.gsub.gsub