フィルタ (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)に戻れる。(をぃ