Repository navigation
Expand file tree
/
Copy pathenvironment.rb
More file actions
90 lines (77 loc) · 1.9 KB
/
Copy pathenvironment.rb
File metadata and controls
90 lines (77 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
class Environment
def initialize(parent = nil)
@variables = {}
@parent = parent
end
def get(name)
if @variables.key?(name)
@variables[name]
elsif @parent
@parent.get(name)
else
raise "Undefined variable: #{name}"
end
end
def set(name, value)
@variables[name] = value
end
def update(name, value)
if @variables.key?(name)
@variables[name] = value
elsif @parent
@parent.update(name, value)
else
raise "Cannot update undefined variable: #{name}"
end
end
def defined?(name)
@variables.key?(name) || (@parent && @parent.defined?(name))
end
end
class KnockObject
attr_reader :class_def, :attributes
def initialize(class_def, attributes)
@class_def = class_def
@attributes = attributes
end
def get_attribute(name)
if @attributes.key?(name)
@attributes[name]
else
raise "Undefined attribute: #{name}"
end
end
def set_attribute(name, value)
if @class_def.attributes.include?(name)
@attributes[name] = value
else
raise "Class #{@class_def.name} does not have attribute: #{name}"
end
end
def to_s
"<#{@class_def.name} instance>"
end
end
class KnockClass
attr_reader :name, :attributes, :methods
def initialize(name, attributes)
@name = name
@attributes = attributes
@methods = {}
end
def add_method(method_name, method_def)
@methods[method_name] = method_def
end
def instantiate(arguments)
# Create instance with attributes
attrs = {}
@attributes.each do |attr|
if arguments.key?(attr)
attrs[attr] = arguments[attr]
else
attrs[attr] = nil
end
end
KnockObject.new(self, attrs)
end
end