class Proc

Public Instance Methods

*(x) click to toggle source

Operator for #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

# 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(object) click to toggle source

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.
# 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
compose(g) click to toggle source

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

# 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(*args) click to toggle source

Curry Proc object into new Proc object.

TODO: Utilize Ruby 1.9's curry method.

# 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 prok.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

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

  instance_eval rec
end
partial(*args) click to toggle source

Convert a Proc object into new partial Proc object.

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

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

This method is similar to #curry.

CREDT Trans

# File lib/more/facets/partial.rb, line 17
def partial(*args)
  Proc.new do |*spice|
    result = args.collect do |a|
      X == a ? spice.pop : a
    end
    call(*result)
  end
end
to_method(object, name=nil) click to toggle source

Convert Proc to method.

plusproc = lambda { |x| x + 1 }
plusproc.to_method(self, 'foo')
X.new.foo(1)  #=> 2
# 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
to_openobject() click to toggle source

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.

# 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