継続で末尾再帰
ライブドアブログ(livedoor Blog)| 読みたいブログが見つかるより。
letを改造すると継続で末尾再帰がもう少しシンプルに書けるような気がします。こんな感じ。
module Let def _set_scope_accessor(scope, assigns) assigns.each do |name, value| scope.instance_eval("def #{name}; @#{name} end") end end def _set_scope_value(scope, assigns) assigns.each do |name, value| scope.instance_variable_set("@#{name}", value) end end def reclet(assigns = {}, &block) scope = Object.new _set_scope_accessor(scope, assigns) _set_scope_value(scope, assigns) scope.instance_eval( 'def reccall(assigns = {}); _set_scope_value(self, assigns); @cc[] end') cc = nil callcc {|i| cc = i } scope.instance_variable_set('@cc', cc) scope.instance_eval(&block) end end include Let def sum(num) reclet :n => num, :acc => 0 do if n == 0 acc else reccall :n => n - 1, :acc => acc + n end end end p sum(1000) # => 500500 p sum(10000) # => 50005000
ほう。常用はしないと思いますが、ネタとしてはなかなか興味深いです。
参照: jijixi’s diary