Skip to content

Instantly share code, notes, and snippets.

@jcoglan
Created January 30, 2009 18:01
Show Gist options
  • Save jcoglan/55170 to your computer and use it in GitHub Desktop.
Save jcoglan/55170 to your computer and use it in GitHub Desktop.
# In file scope.rb
# Expected output:
# BEFORE: 0, AFTER: 0
# BEFORE: 1, AFTER: 1
# BEFORE: 2, AFTER: 2
# BEFORE: 3, AFTER: 3
# BEFORE: 4, AFTER: 4
# BEFORE: 5, AFTER: 5
# BEFORE: 6, AFTER: 6
# 720
# Actual output:
# BEFORE: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0
# BEFORE: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0, AFTER: 0
# 720
class Scope
def initialize
@symbols = {}
# This works:
# define('fact') do |x|
# str = "BEFORE: #{x}"
# result = x == 0 ? 1 : x * self.call('fact', x-1)
# str << ", AFTER: #{x}"
# puts str
# result
# end
# This does not:
path = File.join(File.dirname(__FILE__), 'fact.rb')
instance_eval(File.read(path))
end
def define(name, &body)
@symbols[name] = Function.new(body)
end
def call(name, *args)
@symbols[name].call(*args)
end
end
class Function
def initialize(body)
@body = body
end
def call(*args)
@body.call(*args)
end
end
scope = Scope.new
puts scope.call('fact', 6)
# In file fact.rb
define('fact') do |x|
str = "BEFORE: #{x}"
result = x == 0 ? 1 : x * self.call('fact', x-1)
str << ", AFTER: #{x}"
puts str
result
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment