Apply PIE to nghttpx
[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.keys.each{|k| block.call(self[k])}
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
190     return "{}" if self.size == 0
191     ary=[]
192     keys=self.keys
193     size=keys.size
194     i=0
195     while i<size
196       k=keys[i]
197       ary<<(k._inspect + "=>" + self[k]._inspect)
198       i+=1
199     end
200     "{"+ary.join(", ")+"}"
201   end
202   ##
203   # Return the contents of this hash as a string.
204  #
205   # ISO 15.2.13.4.30 (x)
206   def inspect
207     begin
208       self._inspect
209     rescue SystemStackError
210       "{...}"
211     end
212   end
213   # ISO 15.2.13.4.31 (x)
214   alias to_s inspect
215
216   ##
217   #  call-seq:
218   #     hsh.reject! {| key, value | block }  -> hsh or nil
219   #     hsh.reject!                          -> an_enumerator
220   #
221   #  Equivalent to <code>Hash#delete_if</code>, but returns
222   #  <code>nil</code> if no changes were made.
223   #
224   #  1.8/1.9 Hash#reject! returns Hash; ISO says nothing.
225   #
226   def reject!(&block)
227     return to_enum :reject! unless block
228
229     keys = []
230     self.each{|k,v|
231       if block.call([k, v])
232         keys.push(k)
233       end
234     }
235     return nil if keys.size == 0
236     keys.each{|k|
237       self.delete(k)
238     }
239     self
240   end
241
242   ##
243   #  call-seq:
244   #     hsh.reject {|key, value| block}   -> a_hash
245   #     hsh.reject                        -> an_enumerator
246   #
247   #  Returns a new hash consisting of entries for which the block returns false.
248   #
249   #  If no block is given, an enumerator is returned instead.
250   #
251   #     h = { "a" => 100, "b" => 200, "c" => 300 }
252   #     h.reject {|k,v| k < "b"}  #=> {"b" => 200, "c" => 300}
253   #     h.reject {|k,v| v > 100}  #=> {"a" => 100}
254   #
255   #  1.8/1.9 Hash#reject returns Hash; ISO says nothing.
256   #
257   def reject(&block)
258     return to_enum :reject unless block
259
260     h = {}
261     self.each{|k,v|
262       unless block.call([k, v])
263         h[k] = v
264       end
265     }
266     h
267   end
268
269   ##
270   #  call-seq:
271   #     hsh.select! {| key, value | block }  -> hsh or nil
272   #     hsh.select!                          -> an_enumerator
273   #
274   #  Equivalent to <code>Hash#keep_if</code>, but returns
275   #  <code>nil</code> if no changes were made.
276   #
277   #  1.9 Hash#select! returns Hash; ISO says nothing.
278   #
279   def select!(&block)
280     return to_enum :select! unless block
281
282     keys = []
283     self.each{|k,v|
284       unless block.call([k, v])
285         keys.push(k)
286       end
287     }
288     return nil if keys.size == 0
289     keys.each{|k|
290       self.delete(k)
291     }
292     self
293   end
294
295   ##
296   #  call-seq:
297   #     hsh.select {|key, value| block}   -> a_hash
298   #     hsh.select                        -> an_enumerator
299   #
300   #  Returns a new hash consisting of entries for which the block returns true.
301   #
302   #  If no block is given, an enumerator is returned instead.
303   #
304   #     h = { "a" => 100, "b" => 200, "c" => 300 }
305   #     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
306   #     h.select {|k,v| v < 200}  #=> {"a" => 100}
307   #
308   #  1.9 Hash#select returns Hash; ISO says nothing
309   #
310   def select(&block)
311     return to_enum :select unless block
312
313     h = {}
314     self.each{|k,v|
315       if block.call([k, v])
316         h[k] = v
317       end
318     }
319     h
320   end
321 end
322
323 ##
324 # Hash is enumerable
325 #
326 # ISO 15.2.13.3
327 class Hash
328   include Enumerable
329 end