フィルタ (2)
長い道のりだった……、id:babie:20050921:p7 の続き。って9月かよ!
PHP の Smarty や Perl の TT のように 「|」 でフィルタチェインができたらええなー、と考えてたやつ。
カリー化を使ったお! 使えるお! もっと簡単な実現方法があっても気にしない。カリー化使えて満足。
#!/usr/bin/ruby
# this method was written by HORIKAWA Hisashi.
# See: http://www.nslabs.jp/ramble-200601.rhtml#28
def currying(name, *args)
if name.kind_of?(Proc) or name.kind_of?(Method)
m = name
else
m = method(name)
end
arity = m.arity >= 0 ? m.arity : -m.arity - 1
if arity <= args.size
m.call(*args)
else
lambda {|*a| currying(name, *(args + a))}
end
end
# below code written by babie.
class String
def | m
m.call(self)
end
end
class Filter
def sigh str
"..." + str + "..."
end
def sandwich(bread, str)
bread + str + bread
end
def headtail(prefix, suffix, str)
prefix + str + suffix
end
end
if __FILE__ == $0
# curry
curry_sandwich = currying(Filter.new.method(:sandwich), "---")
p "ahaha" | curry_sandwich
# def
def def_sandwich(*arg)
currying(Filter.new.method(:sandwich), *arg)
end
p "ihihi" | def_sandwich("---")
# eval
eval <<-EVAL
def eval_sandwich(*arg)
currying(Filter.new.method(:sandwich), *arg)
end
EVAL
p "ufufu" | eval_sandwich("---")
# final
class Dummy; end
(Filter.instance_methods - Dummy.instance_methods).each do |name|
eval <<-EVAL
def #{name}(*arg)
currying(Filter.new.method(:#{name}), *arg)
end
EVAL
end
p "fufuf" | sigh
p "ehehe" | sandwich("---")
p "ohoho" | headtail("<<<", ">>>")
end出力:
$ ruby filter.rb "---ahaha---" "---ihihi---" "---ufufu---" "...fufuf..." "---ehehe---" "<<<ohoho>>>"
ここまでくれば Rails に載せるのも、そう遠くはあるめぇ。
これで心おきなく仕事(PHP)に戻れる。(をぃ