Class Proc
In: lib/core/facets/proc/update.rb
lib/core/facets/proc/curry.rb
lib/core/facets/proc/compose.rb
lib/core/facets/proc/to_method.rb
lib/core/facets/proc/bind.rb
lib/more/facets/partial.rb
lib/more/facets/openobject.rb
Parent: Object

Methods

*   bind   compose   curry   partial   to_method   to_openobject  

External Aliases

call -> update
  Use a Proc as an observable.

CREDIT: Tim Pease

Public Instance methods

Operator for Proc#compose and Integer#times_collect/of.

  a = lambda { |x| x + 4 }
  b = lambda { |y| y / 2 }

  (a * b).call(4)  #=> 6
  (b * a).call(4)  #=> 4

CREDIT: Dave

[Source]

# File lib/core/facets/proc/compose.rb, line 29
  def *(x)
    if Integer===x
      # collect times
      c = []
      x.times{|i| c << call(i)}
      c
    else
      # compose procs
      lambda{|*a| self[x[*a]]}
    end
  end

Bind a Proc to an object returning a Method.

NOTE: This version comes from Rails. The old Facets

      version used thread.rb, but I no longer think
      the implementaiton is thread critical. Please
      make a bug report if this proves wrong.

[Source]

# File lib/core/facets/proc/bind.rb, line 10
  def bind(object)
    block, time = self, Time.now
    (class << object; self; end).class_eval do
      method_name = "__bind_#{time.to_i}_#{time.usec}"
      define_method(method_name, &block)
      method = instance_method(method_name)
      remove_method(method_name)
      method
    end.bind(object)
  end

Returns a new proc that is the functional composition of two procs, in order.

  a = lambda { |x| x + 4 }
  b = lambda { |y| y / 2 }

  a.compose(b).call(4)  #=> 6
  b.compose(a).call(4)  #=> 4

CREDIT: Dave

[Source]

# File lib/core/facets/proc/compose.rb, line 14
  def compose(g)
    raise ArgumentError, "arity count mismatch" unless arity == g.arity
    lambda{ |*a| self[ *g[*a] ] }
  end

Curry Proc object into new Proc object.

TODO: Utilize Ruby 1.9‘s curry method.

[Source]

# File lib/core/facets/proc/curry.rb, line 7
  def curry(*args)
    if args.empty?
      idx = (0...arity).to_a
    else
      raise ArgumentError, "argument count is greater than arity (#{args.size} > #{arity})" if args.size > arity
      raise ArgumentError, "arguments must be unique indexes" if args.uniq != args
      raise ArgumentError, "arguments must be indexes" if args.any?{ |a| !Fixnum===a }
      idx = (0...arity).to_a
      idx = args + (idx - args)  
    end

    rec = ''
    idx.each do |i|
      rec << "proc { |a#{i}| "
    end
    rec << "self["
    rec << (0...arity).to_a.collect{|i| "a#{i}"}.join(',')
    rec << "]"
    rec << "}" * arity

    instance_eval rec
  end

Convert a Proc object into new partial Proc object.

  a = proc { |a,b,c| a+b+c }
  b = a.partial(__, 2, __)
  b[1,3] #=> 6

This method is similar to Proc#curry.

CREDT Trans

TODO: Parhaps ArgumentError would suffice, and we don‘t need MissingArgument?

[Source]

# File lib/more/facets/partial.rb, line 27
  def partial(*args)
    Proc.new do |*spice|
      result = args.collect do |a|
        MissingArgument == a ? spice.pop : a
      end
      call(*result)
    end
  end

Convert Proc to method.

  plusproc = lambda { |x| x + 1 }
  plusproc.to_method(self, 'foo')
  X.new.foo(1)  #=> 2

[Source]

# File lib/core/facets/proc/to_method.rb, line 11
  def to_method(object, name=nil)
    #object = object || eval("self", self)
    block, time = self, Time.now
    method_name = name || "__bind_#{time.to_i}_#{time.usec}"
    begin
      (class << object; self; end).class_eval do
        define_method(method_name, &block)
        method = instance_method(method_name)
        remove_method(method_name) unless name
        method
      end.bind(object)
    rescue TypeError
      object.class.class_eval do
        define_method(method_name, &block)
        method = instance_method(method_name)
        remove_method(method_name) unless name
        method
      end.bind(object)
    end
  end

Translates a Proc into an OpenObject. By droping an OpenObject into the Proc, the resulting assignments incured as the procedure is evaluated produce the OpenObject. This technique is simlar to that of MethodProbe.

  p = lambda { |x|
    x.word = "Hello"
  }
  o = p.to_openobject
  o.word #=> "Hello"

NOTE The Proc must have an arity of one —no more and no less.

[Source]

# File lib/more/facets/openobject.rb, line 260
  def to_openobject
    raise ArgumentError, 'bad arity for converting Proc to openobject' if arity != 1
    o = OpenObject.new
    self.call( o )
    o
  end

[Validate]