Class: Proc

Class | Proc
In: | lib/core/facets/proc/bind.rb lib/core/facets/proc/compose.rb lib/core/facets/proc/curry.rb lib/core/facets/proc/to_method.rb lib/core/facets/proc/update.rb lib/more/facets/openobject.rb lib/more/facets/partial.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

*(x)

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(object)

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

compose(g)

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(*args)

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 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)

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 Proc#curry.

CREDT Trans

[Source]

    # 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)

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

to_openobject()

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]