lib/abstractivator/proc_ext.rb in abstractivator-0.0.23 vs lib/abstractivator/proc_ext.rb in abstractivator-0.0.24

- old
+ new

@@ -1,57 +1,81 @@ require 'abstractivator/enumerable_ext' module MethodAndProcExtensions + # returns a version of the procedure that accepts any number of arguments def loosen_args proc do |*args, &block| Proc.loose_call(self, args, &block) end end end class Proc include MethodAndProcExtensions + # composes this procedure with another procedure + # f.compose(g) ==> proc { |x| f.call(g.call(x)) } def compose(other) proc{|x| self.call(other.call(x))} end + # composes procedures. + # compose(f, g, h) returns the procedure + # proc { |x| f.call(g.call(h.call(x))) } def self.compose(*procs) procs.map(&:to_proc).inject_right(identity) { |inner, p| p.compose(inner) } end + # returns the identity function def self.identity proc {|x| x} end + # returns a version of the procedure with the argument list reversed def reverse_args proc do |*args, &block| self.call(*args.reverse, &block) end end + # tries to coerce x into a procedure, then calls it with + # the given argument list. + # If x cannot be coerced into a procedure, returns x. def self.loose_call(x, args, &block) x = x.to_proc if x.respond_to?(:to_proc) - x.respond_to?(:call) or return x + x.callable? or return x args = args.take(x.arity).pad_right(x.arity) if x.arity >= 0 x.call(*args, &block) end end class Method include MethodAndProcExtensions end class UnboundMethod + # returns a version of the procedure that takes the receiver + # (that would otherwise need to be bound with .bind()) as + # the first argument def explicit_receiver proc do |receiver, *args, &block| self.bind(receiver).call(*args, &block) end end end class Array + # A syntactic hack to get hash values. + # xs.map(&:name) works when xs is an array of objects, each with a #name method. (built into ruby) + # xs.map(&[:name]) works when xs is an array of hashes, each with a :name key. + # xs.map(&['name']) works when xs is an array of hashes, each with a 'name' key. def to_proc raise 'size must be exactly one' unless size == 1 proc{|x| x[first]} + end +end + +class Object + def callable? + respond_to?(:call) end end