-
Notifications
You must be signed in to change notification settings - Fork 0
/
about_hashes.rb
139 lines (106 loc) · 3.9 KB
/
about_hashes.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
require File.expand_path(File.dirname(__FILE__) + "/neo")
# TIL:
# - The hash initialised with array as default object -> That default object is not assigned to a key if you attempt to
# access the hash with a non-existent key. It is simply returned whenever you do so. As, in the example, if you are doing
# e.g. hash[:one] << 1, hash[:two] << 2, hash[:three] << 3 then each time the same default array object is returned and
# you are adding the value to the array, so you end up with [1,2,3].
class AboutHashes < Neo::Koan
def test_creating_hashes
empty_hash = {}
assert_equal Hash, empty_hash.class
assert_equal({}, empty_hash)
assert_equal 0, empty_hash.size
end
def test_hash_literals
hash = {one: "uno", two: "dos"}
assert_equal 2, hash.size
end
def test_accessing_hashes
hash = {one: "uno", two: "dos"}
assert_equal "uno", hash[:one]
assert_equal "dos", hash[:two]
assert_equal nil, hash[:doesnt_exist]
end
def test_accessing_hashes_with_fetch
hash = {one: "uno"}
assert_equal "uno", hash.fetch(:one)
assert_raise(KeyError) do
hash.fetch(:doesnt_exist)
end
# THINK ABOUT IT:
#
# Why might you want to use #fetch instead of #[] when accessing hash keys?
# A: #fetch will raise a KeyError when you attempt to retrieve a value from the hash with a key that doesn't exist.
# This can prevent subtle bugs and silent failures. #fetch allows you to provide a 2nd argument that serves as a default
# value should a key not exist. By providing a block, you can also return a dynamically created default value.
end
def test_changing_hashes
hash = {one: "uno", two: "dos"}
hash[:one] = "eins"
expected = {one: "eins", two: "dos"}
assert_equal expected, hash
# Bonus Question: Why was "expected" broken out into a variable
# rather than used as a literal?
# A: Ruby would interpret the hash as a block, causing a syntax error. You could get around this a number of ways,
# e.g. use parentheses to wrap the arguments
end
def test_hash_is_unordered
hash1 = {one: "uno", two: "dos"}
hash2 = {two: "dos", one: "uno"}
assert_equal true, hash1 == hash2
end
def test_hash_keys
hash = {one: "uno", two: "dos"}
assert_equal 2, hash.keys.size
assert_equal true, hash.keys.include?(:one)
assert_equal true, hash.keys.include?(:two)
assert_equal Array, hash.keys.class
end
def test_hash_values
hash = {one: "uno", two: "dos"}
assert_equal 2, hash.values.size
assert_equal true, hash.values.include?("uno")
assert_equal true, hash.values.include?("dos")
assert_equal Array, hash.values.class
end
def test_combining_hashes
hash = {"jim" => 53, "amy" => 20, "dan" => 23}
new_hash = hash.merge({"jim" => 54, "jenny" => 26})
assert_equal true, hash != new_hash
expected = {"jim" => 54, "amy" => 20, "dan" => 23, "jenny" => 26}
assert_equal true, expected == new_hash
end
def test_default_value
hash1 = {}
hash1[:one] = 1
assert_equal 1, hash1[:one]
assert_equal nil, hash1[:two]
hash2 = Hash.new("dos")
hash2[:one] = 1
assert_equal 1, hash2[:one]
assert_equal "dos", hash2[:two]
end
def test_default_value_is_the_same_object
hash = Hash.new([])
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno", "dos"], hash[:one]
assert_equal ["uno", "dos"], hash[:two]
assert_equal ["uno", "dos"], hash[:three]
assert_equal true, hash[:one].equal?(hash[:two])
end
def test_default_value_with_block
hash = Hash.new { |hash, key| hash[key] = [] }
hash[:one] << "uno"
hash[:two] << "dos"
assert_equal ["uno"], hash[:one]
assert_equal ["dos"], hash[:two]
assert_equal [], hash[:three]
end
def test_default_value_attribute
hash = {}
assert_equal nil, hash[:some_key]
hash.default = "peanut"
assert_equal "peanut", hash[:some_key]
end
end