# 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/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/facets/proc/bind.rb, line 12
    def bind(object)
      block, time = self, Time.now
      method_name = "__bind_#{time.to_i}_#{time.usec}"
      object.singleton_class.class_eval do
        define_method(method_name, &block)
        method = instance_method(method_name)
        remove_method(method_name)
        method
      end.bind(object)
    end

bind_to(object) click to toggle source

Bind a procedure to an object. This works wrapping instance_eval on the Proc object and then wrapping this in a new Proc.

    a = [1,2,3]
    p1 = Proc.new{ join(' ') }
    p2 = p1.bind_to(a)
    p2.call  #=> '1 2 3'

    # File lib/facets/proc/bind_to.rb, line 12
    def bind_to(object)
      Proc.new{object.instance_eval(&self)}
    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/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/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(NA,2,NA)
    b[1,3] #=> 6

Note, the #__ method, which used to be used in stay of NA, has been deprecated.

This method is similar to #curry.

CREDT Trans

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

to_method(object, name=nil) click to toggle source

Convert Proc to method.

    object = Object.new

    function = lambda { |x| x + 1 }

    function.to_method(object, 'foo')

    object.foo(1)  #=> 2

    # File lib/facets/proc/to_method.rb, line 16
    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
        object.singleton_class.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