"Florian Frank" wrote:
....
> > this returns a new block that combines the two blocks passed.
>
> I once played around with this:
>
> class Proc
>
>     def compose(other)
>         lambda { |*args| call(*other.call(*args)) }
>     end

My arity preserving solution to this problem was

class Proc
  class << CMP_TABLE = []
    def add_comp(n)
      s = (1..(n < 0 ? 1 - n : n)).collect{|i| "_#{i},"}.join
      a = n >= 0 ? s.chomp(',') : s << '*_'
      self << eval("proc {|f,g| proc {|#{s}| f[*g[#{a}].to_a] }}")
    end
    (-14..14).each {|n| CMP_TABLE.add_comp(n) }
    remove_method :add_comp
  end
  CMP_TABLE.freeze

  def *(other)
    CMP_TABLE[other.arity - 15][self,other]
  end
end

These days one might also want to preserve  "block lambda-ness"  -
which depends on a proc (a Proc instance) being formed using the
"Proc.new  { ... }" or   the "proc { ... }" syntax.

Which brings up the question on how to test  "block lambda-ness"
without writing a C-extension?


/Christoph