call | -> | update |
Use a Proc as an observable.
CREDIT: Tim Pease |
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
# 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.
# 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
# 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.
# 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?
# 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
# 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.
# 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