-
Notifications
You must be signed in to change notification settings - Fork 0
/
about_classes.rb
200 lines (151 loc) · 4.65 KB
/
about_classes.rb
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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
require File.expand_path(File.dirname(__FILE__) + "/neo")
# TIL:
# - Instance variables are stored as symbols within the `instance_variables` array
# - You can retrieve an instance variable with:
# - instance_variable_get("@name")
# - instance_eval("@name")
# - instance_eval { @name }
#
# - All objects support `to_s` and `inspect`
# - Calling inspect on a string returns the string in double quotes with the inner double quotes escaped
class AboutClasses < Neo::Koan
class Dog
end
def test_instances_of_classes_can_be_created_with_new
fido = Dog.new
assert_equal Dog, fido.class
end
# ------------------------------------------------------------------
class Dog2
def set_name(a_name)
@name = a_name
end
end
def test_instance_variables_can_be_set_by_assigning_to_them
fido = Dog2.new
assert_equal [], fido.instance_variables
fido.set_name("Fido")
assert_equal [:@name], fido.instance_variables
end
def test_instance_variables_cannot_be_accessed_outside_the_class
fido = Dog2.new
fido.set_name("Fido")
assert_raise(NoMethodError) do
fido.name
end
assert_raise(SyntaxError) do
eval "fido.@name"
# NOTE: Using eval because the above line is a syntax error.
end
end
def test_you_can_politely_ask_for_instance_variable_values
fido = Dog2.new
fido.set_name("Fido")
assert_equal "Fido", fido.instance_variable_get(:@name)
end
def test_you_can_rip_the_value_out_using_instance_eval
fido = Dog2.new
fido.set_name("Fido")
assert_equal "Fido", fido.instance_eval("@name", __FILE__, __LINE__) # string version
assert_equal "Fido", fido.instance_eval { @name } # block version
end
# ------------------------------------------------------------------
class Dog3
def set_name(a_name)
@name = a_name
end
attr_reader :name
end
def test_you_can_create_accessor_methods_to_return_instance_variables
fido = Dog3.new
fido.set_name("Fido")
assert_equal "Fido", fido.name
end
# ------------------------------------------------------------------
class Dog4
attr_reader :name
def set_name(a_name)
@name = a_name
end
end
def test_attr_reader_will_automatically_define_an_accessor
fido = Dog4.new
fido.set_name("Fido")
assert_equal "Fido", fido.name
end
# ------------------------------------------------------------------
class Dog5
attr_accessor :name
end
def test_attr_accessor_will_automatically_define_both_read_and_write_accessors
fido = Dog5.new
fido.name = "Fido"
assert_equal "Fido", fido.name
end
# ------------------------------------------------------------------
class Dog6
attr_reader :name
def initialize(initial_name)
@name = initial_name
end
end
def test_initialize_provides_initial_values_for_instance_variables
fido = Dog6.new("Fido")
assert_equal "Fido", fido.name
end
def test_args_to_new_must_match_initialize
assert_raise(ArgumentError) do
Dog6.new
end
# THINK ABOUT IT:
# Why is this so?
# A: By writing an initialize method, you ensure that when an object instance is instantiated, it is done with the
# correct number of arguments. You can also ensure the correct type is used within the method. If an ob&ct isn't
# correctly initialised then unexpected behaviour could occur.
end
def test_different_objects_have_different_instance_variables
fido = Dog6.new("Fido")
rover = Dog6.new("Rover")
assert_equal true, rover.name != fido.name
end
# ------------------------------------------------------------------
class Dog7
attr_reader :name
def initialize(initial_name)
@name = initial_name
end
def get_self
self
end
def to_s
@name
end
def inspect
"<Dog named '#{name}'>"
end
end
def test_inside_a_method_self_refers_to_the_containing_object
fido = Dog7.new("Fido")
fidos_self = fido.get_self
assert_equal fido, fidos_self
end
def test_to_s_provides_a_string_version_of_the_object
fido = Dog7.new("Fido")
assert_equal "Fido", fido.to_s
end
def test_to_s_is_used_in_string_interpolation
fido = Dog7.new("Fido")
assert_equal "My dog is #{fido}", "My dog is #{fido}"
end
def test_inspect_provides_a_more_complete_string_version
fido = Dog7.new("Fido")
assert_equal "<Dog named 'Fido'>", fido.inspect
end
def test_all_objects_support_to_s_and_inspect
array = [1, 2, 3]
assert_equal "[1, 2, 3]", array.to_s
assert_equal "[1, 2, 3]", array.inspect
assert_equal "STRING", "STRING".to_s
assert_equal "\"STRING\"", "STRING".inspect
end
end