Ruby メタプログラミングで
module LOOP_EX class ObjectHolder # wrapper object attr_reader :value def initialize v @value = v end end def loop_ex func private_name = (" " + func.to_s).to_sym # original method is callable by private_name alias_method private_name, func # redefine original name by wrapping method define_method func, lambda {|*args| ObjectHolder.new args } # this method should not use from external private func # interface for external define_method func.to_s + "_loop", lambda {|*args| r = ObjectHolder.new args while r.kind_of? ObjectHolder do r = __send__ private_name, *r.value end r } end end class Foo extend LOOP_EX def sum n, acc if n > 0 then sum (n - 1), (acc + n) else acc end end loop_ex :sum end foo = Foo.new p foo.sum_loop(100000, 0)
JavaScript の継続渡しを真似するのはエレガントにできなかったので断念。 id:athos:20110119:p1 のコードをリファクタリングした感じ。マルチスレッドセーフになっています