On 11/20/06, [email protected] [email protected] wrote:
Hi –
On Mon, 20 Nov 2006, spooq wrote:
On 11/20/06, spooq [email protected] wrote:
foo.gsub!.bar
because of the danger of nil from gsub!. That was the impetus for my
idea of using tap in this situation.
Sorry, this was a really bad example from me… I meant the equivalent
using tap notation - foo.tap { gsub! }.bar. There was no way for you
to guess that.
The ! is there to give a heads-up for possible side-effects. Also, I
think I have a different view of chaining than you do.
Maybe you are more confident of your ability to handle complexity than
I am of my ability 
foo.tap { gsub! }.gsub.tap { gsub! }
should be written as
foo.gsub!
foo.gsub.gsub
You’d want a final ! there to make them equivalent 
Are you sure? Let’s look at the original again.
foo.tap { gsub! }.gsub.tap { gsub! }
foo.tap { gsub! } → returns a modified foo
foo.gsub → returns the result of
foo.gsub, which IS NOT FOO
returned_value.tap { gsub! } → modifies the not-foo and returns it
Somewhere along that path, you have gone from passing foo to passing
an anonymous not-foo, and it’s not poke-you-in-the-eye obvious where
that was. If you now expect foo to be returned by this chain (as you
might think when you see the first tap), you will be surprised. If you
expect foo to be modified by the last gsub, you will be surprised. If
you expect chains to leave the original alone (like all the inherently
chainable functions in Ruby do at the moment), you will be surprised.
Thats far too many surprises for my liking.
So how can we rewrite… the anonymous not-foo is only useful as a
return value, seeing as it has no name and all. Let’s make that
explicit.
foo.gsub!
puts foo, somefunc(foo.gsub.gsub)
Almost by definition, if you’re using a bang-function, you need foo
later on, otherwise you would just do
puts somefunc(foo.gsub.gsub.gsub)
and be done with it.
Conclusion : tap-allowing-side-effects and the equivalent,
bang-functions returning self, add nothing except headaches!
I’ll just add that in my own little testbeds, I’ve renamed tap to
“punt” 
punt seems like an equally valid name.
We’re probably at the agree-to-disagree stage, but hopefully it’s been
of interest to both of us and anyone interested in the topic.
We probably are at that stage, but the journey was definitely
worthwhile, so thanks 