From: spooq Date: 2006-11-20T23:50:10+09:00 Subject: Re: #returning and #tap On 11/20/06, dblack@wobblini.net wrote: > Hi -- > > On Mon, 20 Nov 2006, spooq wrote: > > > On 11/20/06, spooq 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 :)