Farrel Lifson wrote:
> Any particular reason you just can't write it like
> 
> some_other_object.method3(value.method1(args).method2(args))

Yes, because it obscures the flow of the data, especially in more 
complex examples.

In the general case, where you may have several intermediate values, and 
where the methods and arguments may not be so conveniently compact, such 
a refactoring seems likely to be hard to understand.  What was a 
top-to-bottom pipeline has become a zigzag flow of data.

Consider this example (sans comments):

   def crumbs_from_path_parts(parts)
     parts.map do |crumb|
       crumb.
         gsub(/\/index/,'').
         sub(/.*--/,'').
         gsub(/ANY|-/,' ').
         sub(/^articles\//,'').
         strip.
         split(/\s+/).
         map { |s| @part_namer.canonicalize(s) }.
         join(" ").
         with_self { |s| @breadcrumb_namer.canonicalize(s) }
     end
   end

You can easily visualize the data flow, top to bottom, as it passes 
through each transformative step.

Now let's say I want to trace the value around the last step.  I would 
do it like this, without disturbing the flow of the pipeline:

   def crumbs_from_path_parts(parts)
     parts.map do |crumb|
       crumb.
         gsub(/\/index/,'').
         sub(/.*--/,'').
         gsub(/ANY|-/,' ').
         sub(/^articles\//,'').
         strip.
         split(/\s+/).
         map { |s| @part_namer.canonicalize(s) }.
         join(" ").
         in_passing { |s| @logger.debug "before naming: #{s}" }.
         with_self  { |s| @breadcrumb_namer.canonicalize(s)   }.
         in_passing { |s| @logger.debug "after naming: #{s}"  }
     end
   end

For cases like this, I think the pipeline is the simplest 
representation.  Rewriting to remove in_passing and with_self would 
increase the code's complexity.

What I want to know is whether Ruby has anything like in_passing and 
with_self built in.  Given how common pipelining is, I would expect so, 
but I can't find them.

Cheers,
Tom