Skip to content

Instantly share code, notes, and snippets.

@nhessler
Forked from JoshCheek/torc.rb
Created December 5, 2015 15:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nhessler/9dcb11ae6d5e6e35e0a0 to your computer and use it in GitHub Desktop.
Save nhessler/9dcb11ae6d5e6e35e0a0 to your computer and use it in GitHub Desktop.
Tail optimized recursive call w/ Nathan at Rubyconf
$depth = 0
at_exit { p depth: $depth }
def record_depth
$depth = caller.length-1 if caller.length-1 > $depth
end
require 'binding_of_caller'
module Torc
def torc(*args)
return [:torc, args] if instance_variable_defined? :@caller
begin
@caller = binding.of_caller(1).eval('__method__')
caller_args = [:start, args]
loop do
caller_args = __send__ @caller, *caller_args.last
return caller_args unless caller_args.respond_to? :first
return caller_args unless caller_args.first == :torc
end
ensure
remove_instance_variable :@caller
end
end
end
def factorial(n)
factorial_helper(1, n)
end
extend Torc
def factorial_helper(acc, n)
record_depth
return acc if n <= 1
torc acc * n, n - 1
end
factorial 1 # => 1
factorial 2 # => 2
factorial 3 # => 6
factorial 4 # => 24
factorial 5 # => 120
factorial 6 # => 720
factorial 100 # => 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
# >> {:depth=>6}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment