diff --git a/ruby/lib/lox/environment.rb b/ruby/lib/lox/environment.rb
index 91366c6..543e07e 100644
--- a/ruby/lib/lox/environment.rb
+++ b/ruby/lib/lox/environment.rb
@@ -2,6 +2,8 @@ require_relative "error"
module Lox
class Environment
+ attr_reader :values, :enclosing
+
def initialize(enclosing = nil)
@enclosing = enclosing
@values = {}
@@ -11,6 +13,12 @@ module Lox
@values[name] = value
end
+ def ancestor(distance)
+ env = self
+ distance.times { env = env.enclosing }
+ env
+ end
+
def get(token)
name = token.lexeme
@@ -23,6 +31,10 @@ module Lox
end
end
+ def get_at(distance, name)
+ ancestor(distance).values.fetch(name)
+ end
+
def assign(name, value)
lexeme = name.lexeme
diff --git a/ruby/test/lox/test_environment.rb b/ruby/test/lox/test_environment.rb
index 1838a3d..fd5b3ee 100644
--- a/ruby/test/lox/test_environment.rb
+++ b/ruby/test/lox/test_environment.rb
@@ -44,4 +44,16 @@ class TestEnvironment < Lox::Test
assert_equal "qux", enclosed.get(NAME_TOKEN)
assert_equal "bar", @env.get(NAME_TOKEN)
end
+
+ def test_get_at
+ @env.define("name", "foo")
+ enclosed = Lox::Environment.new(@env)
+ enclosed.define("name", "bar")
+
+ assert_equal "foo", enclosed.get_at(1, "name")
+ assert_equal "bar", enclosed.get_at(0, "name")
+
+ assert_equal "foo", @env.get_at(0, "name")
+ end
+
end