Upgrade to 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / mrblib / hash.rb
1 ##
2 # Hash
3 #
4 # ISO 15.2.13
5 class Hash
6   ##
7   #  Equality---Two hashes are equal if they each contain the same number
8   #  of keys and if each key-value pair is equal to (according to
9   #  <code>Object#==</code>) the corresponding elements in the other
10   #  hash.
11   #
12   # ISO 15.2.13.4.1
13   def ==(hash)
14     return true if self.equal?(hash)
15     unless Hash === hash
16       return false
17     end
18     return false if self.size != hash.size
19     self.each do |k,v|
20       return false unless hash.key?(k)
21       return false unless self[k] == hash[k]
22     end
23     return true
24   end
25
26   ##
27   # Returns <code>true</code> if <i>hash</i> and <i>other</i> are
28   # both hashes with the same content compared by eql?.
29   #
30   # ISO 15.2.13.4.32 (x)
31   def eql?(hash)
32     return true if self.equal?(hash)
33     unless Hash === hash
34       return false
35     end
36     return false if self.size != hash.size
37     self.each do |k,v|
38       return false unless hash.key?(k)
39       return false unless self[k].eql?(hash[k])
40     end
41     return true
42   end
43
44   ##
45   # Delete the element with the key +key+.
46   # Return the value of the element if +key+
47   # was found. Return nil if nothing was
48   # found. If a block is given, call the
49   # block with the value of the element.
50   #
51   # ISO 15.2.13.4.8
52   def delete(key, &block)
53     if block && !self.has_key?(key)
54       return block.call(key)
55     end
56     self.__delete(key)
57   end
58
59   ##
60   # Calls the given block for each element of +self+
61   # and pass the key and value of each element.
62   #
63   # call-seq:
64   #   hsh.each      {| key, value | block } -> hsh
65   #   hsh.each_pair {| key, value | block } -> hsh
66   #   hsh.each                              -> an_enumerator
67   #   hsh.each_pair                         -> an_enumerator
68   #
69   #
70   # If no block is given, an enumerator is returned instead.
71   #
72   #     h = { "a" => 100, "b" => 200 }
73   #     h.each {|key, value| puts "#{key} is #{value}" }
74   #
75   # <em>produces:</em>
76   #
77   # a is 100
78   # b is 200
79   #
80   # ISO 15.2.13.4.9
81   def each(&block)
82     return to_enum :each unless block
83
84     keys = self.keys
85     vals = self.values
86     len = self.size
87     i = 0
88     while i < len
89       block.call [keys[i], vals[i]]
90       i += 1
91     end
92     self
93   end
94
95   ##
96   # Calls the given block for each element of +self+
97   # and pass the key of each element.
98   #
99   # call-seq:
100   #   hsh.each_key {| key | block } -> hsh
101   #   hsh.each_key                  -> an_enumerator
102   #
103   # If no block is given, an enumerator is returned instead.
104   #
105   #   h = { "a" => 100, "b" => 200 }
106   #   h.each_key {|key| puts key }
107   #
108   # <em>produces:</em>
109   #
110   #  a
111   #  b
112   #
113   # ISO 15.2.13.4.10
114   def each_key(&block)
115     return to_enum :each_key unless block
116
117     self.keys.each{|k| block.call(k)}
118     self
119   end
120
121   ##
122   # Calls the given block for each element of +self+
123   # and pass the value of each element.
124   #
125   # call-seq:
126   #   hsh.each_value {| value | block } -> hsh
127   #   hsh.each_value                    -> an_enumerator
128   #
129   # If no block is given, an enumerator is returned instead.
130   #
131   #  h = { "a" => 100, "b" => 200 }
132   #  h.each_value {|value| puts value }
133   #
134   # <em>produces:</em>
135   #
136   #  100
137   #  200
138   #
139   # ISO 15.2.13.4.11
140   def each_value(&block)
141     return to_enum :each_value unless block
142
143     self.values.each{|v| block.call(v)}
144     self
145   end
146
147   ##
148   # Replaces the contents of <i>hsh</i> with the contents of other hash
149   #
150   # ISO 15.2.13.4.23
151   def replace(hash)
152     raise TypeError, "Hash required (#{hash.class} given)" unless Hash === hash
153     self.clear
154     hash.each_key{|k|
155       self[k] = hash[k]
156     }
157     if hash.default_proc
158       self.default_proc = hash.default_proc
159     else
160       self.default = hash.default
161     end
162     self
163   end
164   # ISO 15.2.13.4.17
165   alias initialize_copy replace
166
167   ##
168   # Return a hash which contains the content of
169   # +self+ and +other+. If a block is given
170   # it will be called for each element with
171   # a duplicate key. The value of the block
172   # will be the final value of this element.
173   #
174   # ISO 15.2.13.4.22
175   def merge(other, &block)
176     raise TypeError, "Hash required (#{other.class} given)" unless Hash === other
177     h = self.dup
178     if block
179       other.each_key{|k|
180         h[k] = (self.has_key?(k))? block.call(k, self[k], other[k]): other[k]
181       }
182     else
183       other.each_key{|k| h[k] = other[k]}
184     end
185     h
186   end
187
188   # internal method for Hash inspection
189   def _inspect(recur_list)
190     return "{}" if self.size == 0
191     return "{...}" if recur_list[self.object_id]
192     recur_list[self.object_id] = true
193     ary=[]
194     keys=self.keys
195     vals=self.values
196     size=keys.size
197     i=0
198     while i<size
199       ary<<(keys[i]._inspect(recur_list) + "=>" + vals[i]._inspect(recur_list))
200       i+=1
201     end
202     "{"+ary.join(", ")+"}"
203   end
204   ##
205   # Return the contents of this hash as a string.
206  #
207   # ISO 15.2.13.4.30 (x)
208   def inspect
209     self._inspect({})
210   end
211   # ISO 15.2.13.4.31 (x)
212   alias to_s inspect
213
214   ##
215   #  call-seq:
216   #     hsh.reject! {| key, value | block }  -> hsh or nil
217   #     hsh.reject!                          -> an_enumerator
218   #
219   #  Equivalent to <code>Hash#delete_if</code>, but returns
220   #  <code>nil</code> if no changes were made.
221   #
222   #  1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
223   #
224   def reject!(&block)
225     return to_enum :reject! unless block
226
227     keys = []
228     self.each{|k,v|
229       if block.call([k, v])
230         keys.push(k)
231       end
232     }
233     return nil if keys.size == 0
234     keys.each{|k|
235       self.delete(k)
236     }
237     self
238   end
239
240   ##
241   #  call-seq:
242   #     hsh.reject {|key, value| block}   -> a_hash
243   #     hsh.reject                        -> an_enumerator
244   #
245   #  Returns a new hash consisting of entries for which the block returns false.
246   #
247   #  If no block is given, an enumerator is returned instead.
248   #
249   #     h = { "a" => 100, "b" => 200, "c" => 300 }
250   #     h.reject {|k,v| k < "b"}  #=> {"b" => 200, "c" => 300}
251   #     h.reject {|k,v| v > 100}  #=> {"a" => 100}
252   #
253   #  1.8/1.9 Hash#reject returns Hash; ISO says nothing.
254   #
255   def reject(&block)
256     return to_enum :reject unless block
257
258     h = {}
259     self.each{|k,v|
260       unless block.call([k, v])
261         h[k] = v
262       end
263     }
264     h
265   end
266
267   ##
268   #  call-seq:
269   #     hsh.select! {| key, value | block }  -> hsh or nil
270   #     hsh.select!                          -> an_enumerator
271   #
272   #  Equivalent to <code>Hash#keep_if</code>, but returns
273   #  <code>nil</code> if no changes were made.
274   #
275   #  1.9 Hash#select! returns Hash; ISO says nothing.
276   #
277   def select!(&block)
278     return to_enum :select! unless block
279
280     keys = []
281     self.each{|k,v|
282       unless block.call([k, v])
283         keys.push(k)
284       end
285     }
286     return nil if keys.size == 0
287     keys.each{|k|
288       self.delete(k)
289     }
290     self
291   end
292
293   ##
294   #  call-seq:
295   #     hsh.select {|key, value| block}   -> a_hash
296   #     hsh.select                        -> an_enumerator
297   #
298   #  Returns a new hash consisting of entries for which the block returns true.
299   #
300   #  If no block is given, an enumerator is returned instead.
301   #
302   #     h = { "a" => 100, "b" => 200, "c" => 300 }
303   #     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
304   #     h.select {|k,v| v < 200}  #=> {"a" => 100}
305   #
306   #  1.9 Hash#select returns Hash; ISO says nothing
307   #
308   def select(&block)
309     return to_enum :select unless block
310
311     h = {}
312     self.each{|k,v|
313       if block.call([k, v])
314         h[k] = v
315       end
316     }
317     h
318   end
319 end
320
321 ##
322 # Hash is enumerable
323 #
324 # ISO 15.2.13.3
325 class Hash
326   include Enumerable
327 end