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
|
##
# Hash
#
# ISO 15.2.13
class Hash
##
# Delete the element with the key +key+.
# Return the value of the element if +key+
# was found. Return nil if nothing was
# found. If a block is given, call the
# block with the value of the element.
#
# ISO 15.2.13.4.8
def delete(key, &block)
if block && ! self.has_key?(key)
block.call(key)
else
self.__delete(key)
end
end
##
# Calls the given block for each element of +self+
# and pass the key and value of each element.
#
# ISO 15.2.13.4.9
def each(&block)
self.keys.each{|k| block.call([k, self[k]])}
self
end
##
# Calls the given block for each element of +self+
# and pass the key of each element.
#
# ISO 15.2.13.4.10
def each_key(&block)
self.keys.each{|k| block.call(k)}
self
end
##
# Calls the given block for each element of +self+
# and pass the value of each element.
#
# ISO 15.2.13.4.11
def each_value(&block)
self.keys.each{|k| block.call(self[k])}
self
end
##
# Create a direct instance of the class Hash.
#
# ISO 15.2.13.4.16
def initialize(*args, &block)
self.__init_core(block, *args)
end
##
# Return a hash which contains the content of
# +self+ and +other+. If a block is given
# it will be called for each element with
# a duplicate key. The value of the block
# will be the final value of this element.
#
# ISO 15.2.13.4.22
def merge(other, &block)
h = {}
raise "can't convert argument into Hash" unless other.respond_to?(:to_hash)
other = other.to_hash
self.each_key{|k| h[k] = self[k]}
if block
other.each_key{|k|
h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
}
else
other.each_key{|k| h[k] = other[k]}
end
h
end
# 1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
def reject!(&b)
keys = []
self.each_key{|k|
v = self[k]
if b.call(k, v)
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
# 1.8/1.9 Hash#reject returns Hash; ISO says nothing.
def reject(&b)
h = {}
self.each_key{|k|
v = self[k]
unless b.call(k, v)
h[k] = v
end
}
h
end
# 1.9 Hash#select! returns Hash; ISO says nothing.
def select!(&b)
keys = []
self.each_key{|k|
v = self[k]
unless b.call(k, v)
keys.push(k)
end
}
return nil if keys.size == 0
keys.each{|k|
self.delete(k)
}
self
end
# 1.9 Hash#select returns Hash; ISO says nothing.
def select(&b)
h = {}
self.each_key{|k|
v = self[k]
if b.call(k, v)
h[k] = v
end
}
h
end
end
##
# Hash is enumerable
#
# ISO 15.2.13.3
module Enumerable; end
class Hash
include Enumerable
end
|