This repository has been archived on 2021-12-03. You can view files and clone it, but cannot push or open issues/pull-requests.
functional/lib/functional.rb

103 lines
1.8 KiB
Ruby
Raw Normal View History

2010-04-19 20:22:54 +02:00
2010-05-20 14:48:42 +02:00
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
2010-04-19 20:22:54 +02:00
class Functional
include Enumerable
def self.method_missing meth, *args, &exe
self.new.send meth, *args, &exe
end
2010-04-20 16:50:59 +02:00
def push_method meth, *args, &exe
@stack.push [meth, exe]+args
2010-04-19 20:22:54 +02:00
self
end
def initialize obj = nil, func = nil, *args
@stack, @obj, @func, @args = [], obj, func, args
end
def collect &exe
2010-04-20 16:50:59 +02:00
push_method :collect, &exe
2010-04-19 20:22:54 +02:00
end
# map/reduce?
def map &exe
2010-04-20 16:50:59 +02:00
push_method :map, &exe
end
# map/reduce?
def reduce &exe
raise "Reserved for MapReduce."
2010-04-19 20:22:54 +02:00
end
2010-04-19 21:08:49 +02:00
2010-04-19 20:22:54 +02:00
def select &exe
2010-04-20 16:50:59 +02:00
push_method :select, &exe
2010-04-19 20:22:54 +02:00
end
2010-05-20 14:48:42 +02:00
def grep r
push_method :select, &r.method( :match)
end
2010-04-19 20:22:54 +02:00
def delete_if &exe
2010-04-20 16:50:59 +02:00
push_method :delete_if, &exe
end
def compact
push_method :compact
end
def together init, &exe
push_method :together, init, &exe
2010-04-19 20:22:54 +02:00
end
def each &exe
return self unless exe
2010-04-20 16:50:59 +02:00
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 }
2010-04-20 18:54:35 +02:00
when :map then lambda {|val| e.call( val).each &pre }
when :reduce
buf = {}
lambda {|val| buf[ val.first] = e.call( *val) }
2010-04-20 16:50:59 +02:00
when :together
2010-04-20 18:54:35 +02:00
buf = a[2].dup
lambda {|val| if e.call val then pre.call buf; buf = a[2].dup+val else buf += val end }
2010-04-20 16:50:59 +02:00
else
$stderr.puts "Whats that? #{m.inspect}"
callstack
end
end
@obj.send @func||:each, *@args, &callstack
2010-04-19 20:22:54 +02:00
end
2010-04-20 18:54:35 +02:00
def p
each &Kernel.method( :p)
end
2010-04-19 20:22:54 +02:00
end