Skip to content

Instantly share code, notes, and snippets.

@lucaong
Last active August 17, 2017 06:18
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lucaong/255778ff69bdaf6a7a3d to your computer and use it in GitHub Desktop.
Save lucaong/255778ff69bdaf6a7a3d to your computer and use it in GitHub Desktop.
Tail Call Optimization in Ruby
require './tail_call_optimization'
class Foo
extend ::TailCallOptimization
tailrec def fact(n, k = 1)
raise ArgumentError, 'n should be >= 1' if n < 1
return k if n == 1
fact(n - 1, n * k)
end
end
f = Foo.new
puts f.fact(15_000)
require 'method_source'
module TailCallOptimization
def tailrec(method_name)
return if @__performing_tco
method = instance_method(method_name)
file, line = method.source_location
name, path = File.basename(file), File.path(file)
options = {
tailcall_optimization: true,
trace_instruction: false
}
RubyVM::InstructionSequence.new(<<-SOURCE, name, path, line - 3, options).eval
class #{self}
begin
@__performing_tco = true
#{method.source}
ensure
remove_instance_variable(:@__performing_tco)
end
end
SOURCE
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment