103 lines
1.8 KiB
Ruby
103 lines
1.8 KiB
Ruby
|
|
class NotRegexp
|
|
def initialize r
|
|
@rx = r
|
|
end
|
|
def match l
|
|
! @rx.match( l)
|
|
end
|
|
def =~ l
|
|
! @rx =~ l
|
|
end
|
|
def -@
|
|
@rx
|
|
end
|
|
end
|
|
|
|
class Regexp
|
|
def -@
|
|
NotRegexp.new self
|
|
end
|
|
end
|
|
|
|
class Functional
|
|
include Enumerable
|
|
|
|
def self.method_missing meth, *args, &exe
|
|
self.new.send meth, *args, &exe
|
|
end
|
|
|
|
def push_method meth, *args, &exe
|
|
@stack.push [meth, exe]+args
|
|
self
|
|
end
|
|
|
|
def initialize obj = nil, func = nil, *args
|
|
@stack, @obj, @func, @args = [], obj, func, args
|
|
end
|
|
|
|
def collect &exe
|
|
push_method :collect, &exe
|
|
end
|
|
|
|
# map/reduce?
|
|
def map &exe
|
|
push_method :map, &exe
|
|
end
|
|
|
|
# map/reduce?
|
|
def reduce &exe
|
|
raise "Reserved for MapReduce."
|
|
end
|
|
|
|
def select &exe
|
|
push_method :select, &exe
|
|
end
|
|
|
|
def grep r
|
|
push_method :select, &r.method( :match)
|
|
end
|
|
|
|
def delete_if &exe
|
|
push_method :delete_if, &exe
|
|
end
|
|
|
|
def compact
|
|
push_method :compact
|
|
end
|
|
|
|
def together init, &exe
|
|
push_method :together, init, &exe
|
|
end
|
|
|
|
def each &exe
|
|
return self unless exe
|
|
callstack = exe
|
|
@stack.reverse.each do |a|
|
|
m, e = *a[0..1]
|
|
pre = callstack
|
|
callstack = case m
|
|
when :collect then lambda {|val| pre.call e.call( val) }
|
|
when :select then lambda {|val| pre.call val if e.call val }
|
|
when :delete_if then lambda {|val| pre.call val unless e.call val }
|
|
when :compact then lambda {|val| pre.call val if val }
|
|
when :map then lambda {|val| e.call( val).each &pre }
|
|
when :reduce
|
|
buf = {}
|
|
lambda {|val| buf[ val.first] = e.call( *val) }
|
|
when :together
|
|
buf = a[2].dup
|
|
lambda {|val| if e.call val then pre.call buf; buf = a[2].dup+val else buf += val end }
|
|
else
|
|
$stderr.puts "Whats that? #{m.inspect}"
|
|
callstack
|
|
end
|
|
end
|
|
@obj.send @func||:each, *@args, &callstack
|
|
end
|
|
|
|
def p
|
|
each &Kernel.method( :p)
|
|
end
|
|
end
|