Adam Sanderson wrote:
> That's neat, this might be handy too:
>
> class Proc
>   def |(other)
>     proc{|*a| other.call(self.call(*a)) }
>   end
> end
>
> I think I got the idea from something on Why's site, though I can't
> find it now.  Anyways if you could now do:
>
> f = lambda {|x| x * 2} | lambda {|x| 0 - x} | lambda {|x| x + 10}
>
> or more verbosely:
>
> a = lambda {|x| x * 2}
> b = lambda {|x| 0 - x}
> c = lambda {|x| x + 10}
>
> f = (a|b|c)
>
> Think of it as unix pipes :)
>   .adam

Depending on the number of processors you might even run into stack size
limits which won't happen with an #inject based solution (see my other
posting).  (Ok, I know that I'm being obsessive about Enumerable#inject -
it was love at first sight. :-)) )

Although this looks nice, when associating Unix pipes you might be tempted
to expect those to execute concurrently which they don't.

We can combine both solutions:

class ProcChain
  def initialize(*procs) @chain = procs end
  def |(proc)
    @chain << proc
    self
  end
  def call(a)
    @chain.inject(a) {|x,pr| pr[x]}
  end
  alias [] call
end

class Proc
  def |(proc)
    ProcChain.new(self, proc)
  end
end

irb(main):039:0> f = lambda {|x| x * 2} | lambda {|x| 0 - x} | lambda {|x|
x + 10}
=> #<ProcChain:0x4a6fed8 @chain=[#<Proc:0x04a70238@(irb):39>,
#<Proc:0x04a70148@(irb):39>, #<Proc:0x04a6ffc8@(irb):39>]>
irb(main):040:0> f[0]
=> 10
irb(main):041:0> f.call 1
=> 8

:-))

Kind regards

    robert