Methods
*
bind
compose
curry
to_method
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
[ + ]
# 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
[ + ]
# 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 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