The Ruby Cross Reference

Implementation: mri jruby rubinius
Version: 1.8.7-p374 1.9.1-p431 1.9.2-p381 1.9.3-p547 2.0.0-p481 2.1.0-p0 2.1.1 2.1.2 HEAD
001 /**********************************************************************
002 
003   hash.c -
004 
005   $Author$
006   created at: Mon Nov 22 18:51:18 JST 1993
007 
008   Copyright (C) 1993-2007 Yukihiro Matsumoto
009   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
010   Copyright (C) 2000  Information-technology Promotion Agency, Japan
011 
012 **********************************************************************/
013 
014 #include "ruby/ruby.h"
015 #include "ruby/st.h"
016 #include "ruby/util.h"
017 
018 #ifdef __APPLE__
019 #include <crt_externs.h>
020 #endif
021 
022 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
023 
024 #define HASH_DELETED  FL_USER1
025 #define HASH_PROC_DEFAULT FL_USER2
026 
027 VALUE
028 rb_hash_freeze(VALUE hash)
029 {
030     return rb_obj_freeze(hash);
031 }
032 
033 VALUE rb_cHash;
034 
035 static VALUE envtbl;
036 static ID id_hash, id_yield, id_default;
037 
038 static int
039 rb_any_cmp(VALUE a, VALUE b)
040 {
041     if (a == b) return 0;
042     if (FIXNUM_P(a) && FIXNUM_P(b)) {
043         return a != b;
044     }
045     if (TYPE(a) == T_STRING && RBASIC(a)->klass == rb_cString &&
046         TYPE(b) == T_STRING && RBASIC(b)->klass == rb_cString) {
047         return rb_str_hash_cmp(a, b);
048     }
049     if (a == Qundef || b == Qundef) return -1;
050     if (SYMBOL_P(a) && SYMBOL_P(b)) {
051         return a != b;
052     }
053 
054     return !rb_eql(a, b);
055 }
056 
057 VALUE
058 rb_hash(VALUE obj)
059 {
060     VALUE hval = rb_funcall(obj, id_hash, 0);
061   retry:
062     switch (TYPE(hval)) {
063       case T_FIXNUM:
064         return hval;
065 
066       case T_BIGNUM:
067         return LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]);
068 
069       default:
070         hval = rb_to_int(hval);
071         goto retry;
072     }
073 }
074 
075 static int
076 rb_any_hash(VALUE a)
077 {
078     VALUE hval;
079     int hnum;
080 
081     switch (TYPE(a)) {
082       case T_FIXNUM:
083       case T_SYMBOL:
084         hnum = (int)a;
085         break;
086 
087       case T_STRING:
088         hnum = rb_str_hash(a);
089         break;
090 
091       default:
092         hval = rb_hash(a);
093         hnum = (int)FIX2LONG(hval);
094     }
095     hnum <<= 1;
096     return RSHIFT(hnum, 1);
097 }
098 
099 static const struct st_hash_type objhash = {
100     rb_any_cmp,
101     rb_any_hash,
102 };
103 
104 static const struct st_hash_type identhash = {
105     st_numcmp,
106     st_numhash,
107 };
108 
109 typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
110 
111 struct foreach_safe_arg {
112     st_table *tbl;
113     st_foreach_func *func;
114     st_data_t arg;
115 };
116 
117 static int
118 foreach_safe_i(st_data_t key, st_data_t value, struct foreach_safe_arg *arg)
119 {
120     int status;
121 
122     if (key == Qundef) return ST_CONTINUE;
123     status = (*arg->func)(key, value, arg->arg);
124     if (status == ST_CONTINUE) {
125         return ST_CHECK;
126     }
127     return status;
128 }
129 
130 void
131 st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
132 {
133     struct foreach_safe_arg arg;
134 
135     arg.tbl = table;
136     arg.func = (st_foreach_func *)func;
137     arg.arg = a;
138     if (st_foreach(table, foreach_safe_i, (st_data_t)&arg)) {
139         rb_raise(rb_eRuntimeError, "hash modified during iteration");
140     }
141 }
142 
143 typedef int rb_foreach_func(VALUE, VALUE, VALUE);
144 
145 struct hash_foreach_arg {
146     VALUE hash;
147     rb_foreach_func *func;
148     VALUE arg;
149 };
150 
151 static int
152 hash_foreach_iter(VALUE key, VALUE value, struct hash_foreach_arg *arg)
153 {
154     int status;
155     st_table *tbl;
156 
157     tbl = RHASH(arg->hash)->ntbl;
158     if (key == Qundef) return ST_CONTINUE;
159     status = (*arg->func)(key, value, arg->arg);
160     if (RHASH(arg->hash)->ntbl != tbl) {
161         rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
162     }
163     switch (status) {
164       case ST_DELETE:
165         st_delete_safe(tbl, (st_data_t*)&key, 0, Qundef);
166         FL_SET(arg->hash, HASH_DELETED);
167       case ST_CONTINUE:
168         break;
169       case ST_STOP:
170         return ST_STOP;
171     }
172     return ST_CHECK;
173 }
174 
175 static VALUE
176 hash_foreach_ensure(VALUE hash)
177 {
178     RHASH(hash)->iter_lev--;
179 
180     if (RHASH(hash)->iter_lev == 0) {
181         if (FL_TEST(hash, HASH_DELETED)) {
182             st_cleanup_safe(RHASH(hash)->ntbl, Qundef);
183             FL_UNSET(hash, HASH_DELETED);
184         }
185     }
186     return 0;
187 }
188 
189 static VALUE
190 hash_foreach_call(struct hash_foreach_arg *arg)
191 {
192     if (st_foreach(RHASH(arg->hash)->ntbl, hash_foreach_iter, (st_data_t)arg)) {
193         rb_raise(rb_eRuntimeError, "hash modified during iteration");
194     }
195     return Qnil;
196 }
197 
198 void
199 rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
200 {
201     struct hash_foreach_arg arg;
202 
203     if (!RHASH(hash)->ntbl)
204         return;
205     RHASH(hash)->iter_lev++;
206     arg.hash = hash;
207     arg.func = (rb_foreach_func *)func;
208     arg.arg  = farg;
209     rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
210 }
211 
212 static VALUE
213 hash_alloc(VALUE klass)
214 {
215     NEWOBJ(hash, struct RHash);
216     OBJSETUP(hash, klass, T_HASH);
217 
218     hash->ifnone = Qnil;
219 
220     return (VALUE)hash;
221 }
222 
223 VALUE
224 rb_hash_new(void)
225 {
226     return hash_alloc(rb_cHash);
227 }
228 
229 VALUE
230 rb_hash_dup(VALUE hash)
231 {
232     NEWOBJ(ret, struct RHash);
233     DUPSETUP(ret, hash);
234 
235     if (!RHASH_EMPTY_P(hash))
236         ret->ntbl = st_copy(RHASH(hash)->ntbl);
237     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
238         FL_SET(ret, HASH_PROC_DEFAULT);
239     }
240     ret->ifnone = RHASH(hash)->ifnone;
241     return (VALUE)ret;
242 }
243 
244 static void
245 rb_hash_modify_check(VALUE hash)
246 {
247     if (OBJ_FROZEN(hash)) rb_error_frozen("hash");
248     if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4)
249         rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
250 }
251 
252 struct st_table *
253 rb_hash_tbl(VALUE hash)
254 {
255     if (!RHASH(hash)->ntbl) {
256         RHASH(hash)->ntbl = st_init_table(&objhash);
257     }
258     return RHASH(hash)->ntbl;
259 }
260 
261 static void
262 rb_hash_modify(VALUE hash)
263 {
264     rb_hash_modify_check(hash);
265     rb_hash_tbl(hash);
266 }
267 
268 /*
269  *  call-seq:
270  *     Hash.new                          => hash
271  *     Hash.new(obj)                     => aHash
272  *     Hash.new {|hash, key| block }     => aHash
273  *
274  *  Returns a new, empty hash. If this hash is subsequently accessed by
275  *  a key that doesn't correspond to a hash entry, the value returned
276  *  depends on the style of <code>new</code> used to create the hash. In
277  *  the first form, the access returns <code>nil</code>. If
278  *  <i>obj</i> is specified, this single object will be used for
279  *  all <em>default values</em>. If a block is specified, it will be
280  *  called with the hash object and the key, and should return the
281  *  default value. It is the block's responsibility to store the value
282  *  in the hash if required.
283  *
284  *     h = Hash.new("Go Fish")
285  *     h["a"] = 100
286  *     h["b"] = 200
287  *     h["a"]           #=> 100
288  *     h["c"]           #=> "Go Fish"
289  *     # The following alters the single default object
290  *     h["c"].upcase!   #=> "GO FISH"
291  *     h["d"]           #=> "GO FISH"
292  *     h.keys           #=> ["a", "b"]
293  *
294  *     # While this creates a new default object each time
295  *     h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
296  *     h["c"]           #=> "Go Fish: c"
297  *     h["c"].upcase!   #=> "GO FISH: C"
298  *     h["d"]           #=> "Go Fish: d"
299  *     h.keys           #=> ["c", "d"]
300  *
301  */
302 
303 static VALUE
304 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
305 {
306     VALUE ifnone;
307 
308     rb_hash_modify(hash);
309     if (rb_block_given_p()) {
310         if (argc > 0) {
311             rb_raise(rb_eArgError, "wrong number of arguments");
312         }
313         RHASH(hash)->ifnone = rb_block_proc();
314         FL_SET(hash, HASH_PROC_DEFAULT);
315     }
316     else {
317         rb_scan_args(argc, argv, "01", &ifnone);
318         RHASH(hash)->ifnone = ifnone;
319     }
320 
321     return hash;
322 }
323 
324 /*
325  *  call-seq:
326  *     Hash[ [key =>|, value]* ]   => hash
327  *
328  *  Creates a new hash populated with the given objects. Equivalent to
329  *  the literal <code>{ <i>key</i>, <i>value</i>, ... }</code>. Keys and
330  *  values occur in pairs, so there must be an even number of arguments.
331  *
332  *     Hash["a", 100, "b", 200]       #=> {"a"=>100, "b"=>200}
333  *     Hash["a" => 100, "b" => 200]   #=> {"a"=>100, "b"=>200}
334  *     { "a" => 100, "b" => 200 }     #=> {"a"=>100, "b"=>200}
335  */
336 
337 static VALUE
338 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
339 {
340     VALUE hash, tmp;
341     int i;
342 
343     if (argc == 1) {
344         tmp = rb_hash_s_try_convert(Qnil, argv[0]);
345         if (!NIL_P(tmp)) {
346             hash = hash_alloc(klass);
347             if (RHASH(tmp)->ntbl) {
348                 RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
349             }
350             return hash;
351         }
352 
353         tmp = rb_check_array_type(argv[0]);
354         if (!NIL_P(tmp)) {
355             long i;
356 
357             hash = hash_alloc(klass);
358             for (i = 0; i < RARRAY_LEN(tmp); ++i) {
359                 VALUE v = rb_check_array_type(RARRAY_PTR(tmp)[i]);
360                 VALUE key, val = Qnil;
361 
362                 if (NIL_P(v)) continue;
363                 switch (RARRAY_LEN(v)) {
364                   case 2:
365                     val = RARRAY_PTR(v)[1];
366                   case 1:
367                     key = RARRAY_PTR(v)[0];
368                     rb_hash_aset(hash, key, val);
369                 }
370             }
371             return hash;
372         }
373     }
374     if (argc % 2 != 0) {
375         rb_raise(rb_eArgError, "odd number of arguments for Hash");
376     }
377 
378     hash = hash_alloc(klass);
379     for (i=0; i<argc; i+=2) {
380         rb_hash_aset(hash, argv[i], argv[i + 1]);
381     }
382 
383     return hash;
384 }
385 
386 static VALUE
387 to_hash(VALUE hash)
388 {
389     return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
390 }
391 
392 /*
393  *  call-seq:
394  *     Hash.try_convert(obj) -> hash or nil
395  *
396  *  Try to convert <i>obj</i> into a hash, using to_hash method.
397  *  Returns converted hash or nil if <i>obj</i> cannot be converted
398  *  for any reason.
399  *
400  *     Hash.try_convert({1=>2})   # => {1=>2}
401  *     Hash.try_convert("1=>2")   # => nil
402  */
403 static VALUE
404 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
405 {
406     return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
407 }
408 
409 static int
410 rb_hash_rehash_i(VALUE key, VALUE value, st_table *tbl)
411 {
412     if (key != Qundef) st_insert(tbl, key, value);
413     return ST_CONTINUE;
414 }
415 
416 /*
417  *  call-seq:
418  *     hsh.rehash -> hsh
419  *
420  *  Rebuilds the hash based on the current hash values for each key. If
421  *  values of key objects have changed since they were inserted, this
422  *  method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is
423  *  called while an iterator is traversing the hash, an
424  *  <code>RuntimeError</code> will be raised in the iterator.
425  *
426  *     a = [ "a", "b" ]
427  *     c = [ "c", "d" ]
428  *     h = { a => 100, c => 300 }
429  *     h[a]       #=> 100
430  *     a[0] = "z"
431  *     h[a]       #=> nil
432  *     h.rehash   #=> {["z", "b"]=>100, ["c", "d"]=>300}
433  *     h[a]       #=> 100
434  */
435 
436 static VALUE
437 rb_hash_rehash(VALUE hash)
438 {
439     st_table *tbl;
440 
441     if (RHASH(hash)->iter_lev > 0) {
442         rb_raise(rb_eRuntimeError, "rehash during iteration");
443     }
444     rb_hash_modify_check(hash);
445     if (!RHASH(hash)->ntbl)
446         return hash;
447     tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
448     rb_hash_foreach(hash, rb_hash_rehash_i, (st_data_t)tbl);
449     st_free_table(RHASH(hash)->ntbl);
450     RHASH(hash)->ntbl = tbl;
451 
452     return hash;
453 }
454 
455 /*
456  *  call-seq:
457  *     hsh[key]    =>  value
458  *
459  *  Element Reference---Retrieves the <i>value</i> object corresponding
460  *  to the <i>key</i> object. If not found, returns the a default value (see
461  *  <code>Hash::new</code> for details).
462  *
463  *     h = { "a" => 100, "b" => 200 }
464  *     h["a"]   #=> 100
465  *     h["c"]   #=> nil
466  *
467  */
468 
469 VALUE
470 rb_hash_aref(VALUE hash, VALUE key)
471 {
472     VALUE val;
473 
474     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
475         return rb_funcall(hash, id_default, 1, key);
476     }
477     return val;
478 }
479 
480 VALUE
481 rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
482 {
483     VALUE val;
484 
485     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
486         return def; /* without Hash#default */
487     }
488     return val;
489 }
490 
491 VALUE
492 rb_hash_lookup(VALUE hash, VALUE key)
493 {
494     return rb_hash_lookup2(hash, key, Qnil);
495 }
496 
497 /*
498  *  call-seq:
499  *     hsh.fetch(key [, default] )       => obj
500  *     hsh.fetch(key) {| key | block }   => obj
501  *
502  *  Returns a value from the hash for the given key. If the key can't be
503  *  found, there are several options: With no other arguments, it will
504  *  raise an <code>KeyError</code> exception; if <i>default</i> is
505  *  given, then that will be returned; if the optional code block is
506  *  specified, then that will be run and its result returned.
507  *
508  *     h = { "a" => 100, "b" => 200 }
509  *     h.fetch("a")                            #=> 100
510  *     h.fetch("z", "go fish")                 #=> "go fish"
511  *     h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"
512  *
513  *  The following example shows that an exception is raised if the key
514  *  is not found and a default value is not supplied.
515  *
516  *     h = { "a" => 100, "b" => 200 }
517  *     h.fetch("z")
518  *
519  *  <em>produces:</em>
520  *
521  *     prog.rb:2:in `fetch': key not found (KeyError)
522  *      from prog.rb:2
523  *
524  */
525 
526 static VALUE
527 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
528 {
529     VALUE key, if_none;
530     VALUE val;
531     long block_given;
532 
533     rb_scan_args(argc, argv, "11", &key, &if_none);
534 
535     block_given = rb_block_given_p();
536     if (block_given && argc == 2) {
537         rb_warn("block supersedes default value argument");
538     }
539     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
540         if (block_given) return rb_yield(key);
541         if (argc == 1) {
542             rb_raise(rb_eKeyError, "key not found");
543         }
544         return if_none;
545     }
546     return val;
547 }
548 
549 VALUE
550 rb_hash_fetch(VALUE hash, VALUE key)
551 {
552     return rb_hash_fetch_m(1, &key, hash);
553 }
554 
555 /*
556  *  call-seq:
557  *     hsh.default(key=nil)   => obj
558  *
559  *  Returns the default value, the value that would be returned by
560  *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
561  *  See also <code>Hash::new</code> and <code>Hash#default=</code>.
562  *
563  *     h = Hash.new                            #=> {}
564  *     h.default                               #=> nil
565  *     h.default(2)                            #=> nil
566  *
567  *     h = Hash.new("cat")                     #=> {}
568  *     h.default                               #=> "cat"
569  *     h.default(2)                            #=> "cat"
570  *
571  *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
572  *     h.default                               #=> nil
573  *     h.default(2)                            #=> 20
574  */
575 
576 static VALUE
577 rb_hash_default(int argc, VALUE *argv, VALUE hash)
578 {
579     VALUE key;
580 
581     rb_scan_args(argc, argv, "01", &key);
582     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
583         if (argc == 0) return Qnil;
584         return rb_funcall(RHASH(hash)->ifnone, id_yield, 2, hash, key);
585     }
586     return RHASH(hash)->ifnone;
587 }
588 
589 /*
590  *  call-seq:
591  *     hsh.default = obj     => obj
592  *
593  *  Sets the default value, the value returned for a key that does not
594  *  exist in the hash. It is not possible to set the a default to a
595  *  <code>Proc</code> that will be executed on each key lookup.
596  *
597  *     h = { "a" => 100, "b" => 200 }
598  *     h.default = "Go fish"
599  *     h["a"]     #=> 100
600  *     h["z"]     #=> "Go fish"
601  *     # This doesn't do what you might hope...
602  *     h.default = proc do |hash, key|
603  *       hash[key] = key + key
604  *     end
605  *     h[2]       #=> #<Proc:0x401b3948@-:6>
606  *     h["cat"]   #=> #<Proc:0x401b3948@-:6>
607  */
608 
609 static VALUE
610 rb_hash_set_default(VALUE hash, VALUE ifnone)
611 {
612     rb_hash_modify(hash);
613     RHASH(hash)->ifnone = ifnone;
614     FL_UNSET(hash, HASH_PROC_DEFAULT);
615     return ifnone;
616 }
617 
618 /*
619  *  call-seq:
620  *     hsh.default_proc -> anObject
621  *
622  *  If <code>Hash::new</code> was invoked with a block, return that
623  *  block, otherwise return <code>nil</code>.
624  *
625  *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}
626  *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
627  *     a = []                             #=> []
628  *     p.call(a, 2)
629  *     a                                  #=> [nil, nil, 4]
630  */
631 
632 
633 static VALUE
634 rb_hash_default_proc(VALUE hash)
635 {
636     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
637         return RHASH(hash)->ifnone;
638     }
639     return Qnil;
640 }
641 
642 VALUE rb_obj_is_proc(VALUE proc);
643 
644 /*
645  *  call-seq:
646  *     hsh.default_proc = proc_obj     => proc_obj
647  *
648  *  Sets the default proc to be executed on each key lookup.
649  *
650  *     h.default_proc = proc do |hash, key|
651  *       hash[key] = key + key
652  *     end
653  *     h[2]       #=> 4
654  *     h["cat"]   #=> "catcat"
655  */
656 
657 static VALUE
658 rb_hash_set_default_proc(VALUE hash, VALUE proc)
659 {
660     VALUE b;
661 
662     rb_hash_modify(hash);
663     b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
664     if (NIL_P(b) || !rb_obj_is_proc(b)) {
665         rb_raise(rb_eTypeError,
666                  "wrong default_proc type %s (expected Proc)",
667                  rb_obj_classname(proc));
668     }
669     proc = b;
670     RHASH(hash)->ifnone = proc;
671     FL_SET(hash, HASH_PROC_DEFAULT);
672     return proc;
673 }
674 
675 static int
676 key_i(VALUE key, VALUE value, VALUE *args)
677 {
678     if (rb_equal(value, args[0])) {
679         args[1] = key;
680         return ST_STOP;
681     }
682     return ST_CONTINUE;
683 }
684 
685 /*
686  *  call-seq:
687  *     hsh.key(value)    => key
688  *
689  *  Returns the key for a given value. If not found, returns <code>nil</code>.
690  *
691  *     h = { "a" => 100, "b" => 200 }
692  *     h.key(200)   #=> "b"
693  *     h.key(999)   #=> nil
694  *
695  */
696 
697 static VALUE
698 rb_hash_key(VALUE hash, VALUE value)
699 {
700     VALUE args[2];
701 
702     args[0] = value;
703     args[1] = Qnil;
704 
705     rb_hash_foreach(hash, key_i, (st_data_t)args);
706 
707     return args[1];
708 }
709 
710 /* :nodoc: */
711 static VALUE
712 rb_hash_index(VALUE hash, VALUE value)
713 {
714     rb_warn("Hash#index is deprecated; use Hash#key");
715     return rb_hash_key(hash, value);
716 }
717 
718 static VALUE
719 rb_hash_delete_key(VALUE hash, VALUE key)
720 {
721     st_data_t ktmp = (st_data_t)key, val;
722 
723     if (!RHASH(hash)->ntbl)
724         return Qundef;
725     if (RHASH(hash)->iter_lev > 0) {
726         if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, Qundef)) {
727             FL_SET(hash, HASH_DELETED);
728             return (VALUE)val;
729         }
730     }
731     else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
732         return (VALUE)val;
733     return Qundef;
734 }
735 
736 /*
737  *  call-seq:
738  *     hsh.delete(key)                   => value
739  *     hsh.delete(key) {| key | block }  => value
740  *
741  *  Deletes and returns a key-value pair from <i>hsh</i> whose key is
742  *  equal to <i>key</i>. If the key is not found, returns the
743  *  <em>default value</em>. If the optional code block is given and the
744  *  key is not found, pass in the key and return the result of
745  *  <i>block</i>.
746  *
747  *     h = { "a" => 100, "b" => 200 }
748  *     h.delete("a")                              #=> 100
749  *     h.delete("z")                              #=> nil
750  *     h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
751  *
752  */
753 
754 VALUE
755 rb_hash_delete(VALUE hash, VALUE key)
756 {
757     VALUE val;
758 
759     rb_hash_modify(hash);
760     val = rb_hash_delete_key(hash, key);
761     if (val != Qundef) return val;
762     if (rb_block_given_p()) {
763         return rb_yield(key);
764     }
765     return Qnil;
766 }
767 
768 struct shift_var {
769     VALUE key;
770     VALUE val;
771 };
772 
773 static int
774 shift_i(VALUE key, VALUE value, struct shift_var *var)
775 {
776     if (key == Qundef) return ST_CONTINUE;
777     if (var->key != Qundef) return ST_STOP;
778     var->key = key;
779     var->val = value;
780     return ST_DELETE;
781 }
782 
783 static int
784 shift_i_safe(VALUE key, VALUE value, struct shift_var *var)
785 {
786     if (key == Qundef) return ST_CONTINUE;
787     var->key = key;
788     var->val = value;
789     return ST_STOP;
790 }
791 
792 /*
793  *  call-seq:
794  *     hsh.shift -> anArray or obj
795  *
796  *  Removes a key-value pair from <i>hsh</i> and returns it as the
797  *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
798  *  the hash's default value if the hash is empty.
799  *
800  *     h = { 1 => "a", 2 => "b", 3 => "c" }
801  *     h.shift   #=> [1, "a"]
802  *     h         #=> {2=>"b", 3=>"c"}
803  */
804 
805 static VALUE
806 rb_hash_shift(VALUE hash)
807 {
808     struct shift_var var;
809 
810     rb_hash_modify(hash);
811     var.key = Qundef;
812     rb_hash_foreach(hash, RHASH(hash)->iter_lev > 0 ? shift_i_safe : shift_i,
813                     (st_data_t)&var);
814 
815     if (var.key != Qundef) {
816         if (RHASH(hash)->iter_lev > 0) {
817             rb_hash_delete_key(hash, var.key);
818         }
819         return rb_assoc_new(var.key, var.val);
820     }
821     else if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
822         return rb_funcall(RHASH(hash)->ifnone, id_yield, 2, hash, Qnil);
823     }
824     else {
825         return RHASH(hash)->ifnone;
826     }
827 }
828 
829 static int
830 delete_if_i(VALUE key, VALUE value, VALUE hash)
831 {
832     if (key == Qundef) return ST_CONTINUE;
833     if (RTEST(rb_yield_values(2, key, value))) {
834         rb_hash_delete_key(hash, key);
835     }
836     return ST_CONTINUE;
837 }
838 
839 /*
840  *  call-seq:
841  *     hsh.delete_if {| key, value | block }  -> hsh
842  *
843  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
844  *  evaluates to <code>true</code>.
845  *
846  *     h = { "a" => 100, "b" => 200, "c" => 300 }
847  *     h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
848  *
849  */
850 
851 VALUE
852 rb_hash_delete_if(VALUE hash)
853 {
854     RETURN_ENUMERATOR(hash, 0, 0);
855     rb_hash_modify(hash);
856     rb_hash_foreach(hash, delete_if_i, hash);
857     return hash;
858 }
859 
860 /*
861  *  call-seq:
862  *     hsh.reject! {| key, value | block }  -> hsh or nil
863  *
864  *  Equivalent to <code>Hash#delete_if</code>, but returns
865  *  <code>nil</code> if no changes were made.
866  */
867 
868 VALUE
869 rb_hash_reject_bang(VALUE hash)
870 {
871     int n;
872 
873     RETURN_ENUMERATOR(hash, 0, 0);
874     if (!RHASH(hash)->ntbl)
875         return Qnil;
876     n = RHASH(hash)->ntbl->num_entries;
877     rb_hash_delete_if(hash);
878     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
879     return hash;
880 }
881 
882 /*
883  *  call-seq:
884  *     hsh.reject {| key, value | block }  -> a_hash
885  *
886  *  Same as <code>Hash#delete_if</code>, but works on (and returns) a
887  *  copy of the <i>hsh</i>. Equivalent to
888  *  <code><i>hsh</i>.dup.delete_if</code>.
889  *
890  */
891 
892 static VALUE
893 rb_hash_reject(VALUE hash)
894 {
895     return rb_hash_delete_if(rb_obj_dup(hash));
896 }
897 
898 /*
899  * call-seq:
900  *   hsh.values_at(key, ...)   => array
901  *
902  * Return an array containing the values associated with the given keys.
903  * Also see <code>Hash.select</code>.
904  *
905  *   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
906  *   h.values_at("cow", "cat")  #=> ["bovine", "feline"]
907  */
908 
909 VALUE
910 rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
911 {
912     VALUE result = rb_ary_new2(argc);
913     long i;
914 
915     for (i=0; i<argc; i++) {
916         rb_ary_push(result, rb_hash_aref(hash, argv[i]));
917     }
918     return result;
919 }
920 
921 static int
922 select_i(VALUE key, VALUE value, VALUE result)
923 {
924     if (key == Qundef) return ST_CONTINUE;
925     if (RTEST(rb_yield_values(2, key, value)))
926         rb_hash_aset(result, key, value);
927     return ST_CONTINUE;
928 }
929 
930 /*
931  *  call-seq:
932  *     hsh.select {|key, value| block}   => a_hash
933  *
934  *  Returns a new hash consisting of entries which the block returns true.
935  *
936  *     h = { "a" => 100, "b" => 200, "c" => 300 }
937  *     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
938  *     h.select {|k,v| v < 200}  #=> {"a" => 100}
939  */
940 
941 VALUE
942 rb_hash_select(VALUE hash)
943 {
944     VALUE result;
945 
946     RETURN_ENUMERATOR(hash, 0, 0);
947     result = rb_hash_new();
948     rb_hash_foreach(hash, select_i, result);
949     return result;
950 }
951 
952 static int
953 clear_i(VALUE key, VALUE value, VALUE dummy)
954 {
955     return ST_DELETE;
956 }
957 
958 /*
959  *  call-seq:
960  *     hsh.clear -> hsh
961  *
962  *  Removes all key-value pairs from <i>hsh</i>.
963  *
964  *     h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
965  *     h.clear                          #=> {}
966  *
967  */
968 
969 static VALUE
970 rb_hash_clear(VALUE hash)
971 {
972     rb_hash_modify_check(hash);
973     if (!RHASH(hash)->ntbl)
974         return hash;
975     if (RHASH(hash)->ntbl->num_entries > 0) {
976         if (RHASH(hash)->iter_lev > 0)
977             rb_hash_foreach(hash, clear_i, 0);
978         else
979             st_clear(RHASH(hash)->ntbl);
980     }
981 
982     return hash;
983 }
984 
985 /*
986  *  call-seq:
987  *     hsh[key] = value        => value
988  *     hsh.store(key, value)   => value
989  *
990  *  Element Assignment---Associates the value given by
991  *  <i>value</i> with the key given by <i>key</i>.
992  *  <i>key</i> should not have its value changed while it is in
993  *  use as a key (a <code>String</code> passed as a key will be
994  *  duplicated and frozen).
995  *
996  *     h = { "a" => 100, "b" => 200 }
997  *     h["a"] = 9
998  *     h["c"] = 4
999  *     h   #=> {"a"=>9, "b"=>200, "c"=>4}
1000  *
1001  */
1002 
1003 VALUE
1004 rb_hash_aset(VALUE hash, VALUE key, VALUE val)
1005 {
1006     rb_hash_modify(hash);
1007     if (RHASH(hash)->ntbl->type == &identhash ||
1008         TYPE(key) != T_STRING || st_lookup(RHASH(hash)->ntbl, key, 0)) {
1009         st_insert(RHASH(hash)->ntbl, key, val);
1010     }
1011     else {
1012         st_add_direct(RHASH(hash)->ntbl, rb_str_new4(key), val);
1013     }
1014     return val;
1015 }
1016 
1017 static int
1018 replace_i(VALUE key, VALUE val, VALUE hash)
1019 {
1020     if (key != Qundef) {
1021         rb_hash_aset(hash, key, val);
1022     }
1023 
1024     return ST_CONTINUE;
1025 }
1026 
1027 /*
1028  *  call-seq:
1029  *     hsh.replace(other_hash) -> hsh
1030  *
1031  *  Replaces the contents of <i>hsh</i> with the contents of
1032  *  <i>other_hash</i>.
1033  *
1034  *     h = { "a" => 100, "b" => 200 }
1035  *     h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
1036  *
1037  */
1038 
1039 static VALUE
1040 rb_hash_replace(VALUE hash, VALUE hash2)
1041 {
1042     hash2 = to_hash(hash2);
1043     if (hash == hash2) return hash;
1044     rb_hash_clear(hash);
1045     rb_hash_foreach(hash2, replace_i, hash);
1046     RHASH(hash)->ifnone = RHASH(hash2)->ifnone;
1047     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
1048         FL_SET(hash, HASH_PROC_DEFAULT);
1049     }
1050     else {
1051         FL_UNSET(hash, HASH_PROC_DEFAULT);
1052     }
1053 
1054     return hash;
1055 }
1056 
1057 /*
1058  *  call-seq:
1059  *     hsh.length    =>  fixnum
1060  *     hsh.size      =>  fixnum
1061  *
1062  *  Returns the number of key-value pairs in the hash.
1063  *
1064  *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
1065  *     h.length        #=> 4
1066  *     h.delete("a")   #=> 200
1067  *     h.length        #=> 3
1068  */
1069 
1070 static VALUE
1071 rb_hash_size(VALUE hash)
1072 {
1073     if (!RHASH(hash)->ntbl)
1074         return INT2FIX(0);
1075     return INT2FIX(RHASH(hash)->ntbl->num_entries);
1076 }
1077 
1078 
1079 /*
1080  *  call-seq:
1081  *     hsh.empty?    => true or false
1082  *
1083  *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
1084  *
1085  *     {}.empty?   #=> true
1086  *
1087  */
1088 
1089 static VALUE
1090 rb_hash_empty_p(VALUE hash)
1091 {
1092     return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
1093 }
1094 
1095 static int
1096 each_value_i(VALUE key, VALUE value)
1097 {
1098     if (key == Qundef) return ST_CONTINUE;
1099     rb_yield(value);
1100     return ST_CONTINUE;
1101 }
1102 
1103 /*
1104  *  call-seq:
1105  *     hsh.each_value {| value | block } -> hsh
1106  *
1107  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the
1108  *  value as a parameter.
1109  *
1110  *     h = { "a" => 100, "b" => 200 }
1111  *     h.each_value {|value| puts value }
1112  *
1113  *  <em>produces:</em>
1114  *
1115  *     100
1116  *     200
1117  */
1118 
1119 static VALUE
1120 rb_hash_each_value(VALUE hash)
1121 {
1122     RETURN_ENUMERATOR(hash, 0, 0);
1123     rb_hash_foreach(hash, each_value_i, 0);
1124     return hash;
1125 }
1126 
1127 static int
1128 each_key_i(VALUE key, VALUE value)
1129 {
1130     if (key == Qundef) return ST_CONTINUE;
1131     rb_yield(key);
1132     return ST_CONTINUE;
1133 }
1134 
1135 /*
1136  *  call-seq:
1137  *     hsh.each_key {| key | block } -> hsh
1138  *
1139  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
1140  *  as a parameter.
1141  *
1142  *     h = { "a" => 100, "b" => 200 }
1143  *     h.each_key {|key| puts key }
1144  *
1145  *  <em>produces:</em>
1146  *
1147  *     a
1148  *     b
1149  */
1150 static VALUE
1151 rb_hash_each_key(VALUE hash)
1152 {
1153     RETURN_ENUMERATOR(hash, 0, 0);
1154     rb_hash_foreach(hash, each_key_i, 0);
1155     return hash;
1156 }
1157 
1158 static int
1159 each_pair_i(VALUE key, VALUE value)
1160 {
1161     if (key == Qundef) return ST_CONTINUE;
1162     rb_yield(rb_assoc_new(key, value));
1163     return ST_CONTINUE;
1164 }
1165 
1166 /*
1167  *  call-seq:
1168  *     hsh.each {| key, value | block } -> hsh
1169  *     hsh.each_pair {| key, value | block } -> hsh
1170  *
1171  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
1172  *  pair as parameters.
1173  *
1174  *     h = { "a" => 100, "b" => 200 }
1175  *     h.each {|key, value| puts "#{key} is #{value}" }
1176  *
1177  *  <em>produces:</em>
1178  *
1179  *     a is 100
1180  *     b is 200
1181  *
1182  */
1183 
1184 static VALUE
1185 rb_hash_each_pair(VALUE hash)
1186 {
1187     RETURN_ENUMERATOR(hash, 0, 0);
1188     rb_hash_foreach(hash, each_pair_i, 0);
1189     return hash;
1190 }
1191 
1192 static int
1193 to_a_i(VALUE key, VALUE value, VALUE ary)
1194 {
1195     if (key == Qundef) return ST_CONTINUE;
1196     rb_ary_push(ary, rb_assoc_new(key, value));
1197     return ST_CONTINUE;
1198 }
1199 
1200 /*
1201  *  call-seq:
1202  *     hsh.to_a -> array
1203  *
1204  *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
1205  *  value</i> <code>]</code> arrays.
1206  *
1207  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
1208  *     h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
1209  */
1210 
1211 static VALUE
1212 rb_hash_to_a(VALUE hash)
1213 {
1214     VALUE ary;
1215 
1216     ary = rb_ary_new();
1217     rb_hash_foreach(hash, to_a_i, ary);
1218     OBJ_INFECT(ary, hash);
1219 
1220     return ary;
1221 }
1222 
1223 static int
1224 inspect_i(VALUE key, VALUE value, VALUE str)
1225 {
1226     VALUE str2;
1227 
1228     if (key == Qundef) return ST_CONTINUE;
1229     if (RSTRING_LEN(str) > 1) {
1230         rb_str_cat2(str, ", ");
1231     }
1232     str2 = rb_inspect(key);
1233     rb_str_buf_append(str, str2);
1234     OBJ_INFECT(str, str2);
1235     rb_str_buf_cat2(str, "=>");
1236     str2 = rb_inspect(value);
1237     rb_str_buf_append(str, str2);
1238     OBJ_INFECT(str, str2);
1239 
1240     return ST_CONTINUE;
1241 }
1242 
1243 static VALUE
1244 inspect_hash(VALUE hash, VALUE dummy, int recur)
1245 {
1246     VALUE str;
1247 
1248     if (recur) return rb_usascii_str_new2("{...}");
1249     str = rb_str_buf_new2("{");
1250     rb_hash_foreach(hash, inspect_i, str);
1251     rb_str_buf_cat2(str, "}");
1252     OBJ_INFECT(str, hash);
1253 
1254     return str;
1255 }
1256 
1257 /*
1258  * call-seq:
1259  *   hsh.to_s   => string
1260  *   hsh.inspect  => string
1261  *
1262  * Return the contents of this hash as a string.
1263  *
1264  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
1265  *     h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
1266  */
1267 
1268 static VALUE
1269 rb_hash_inspect(VALUE hash)
1270 {
1271     if (RHASH_EMPTY_P(hash))
1272         return rb_usascii_str_new2("{}");
1273     return rb_exec_recursive(inspect_hash, hash, 0);
1274 }
1275 
1276 /*
1277  * call-seq:
1278  *    hsh.to_hash   => hsh
1279  *
1280  * Returns <i>self</i>.
1281  */
1282 
1283 static VALUE
1284 rb_hash_to_hash(VALUE hash)
1285 {
1286     return hash;
1287 }
1288 
1289 static int
1290 keys_i(VALUE key, VALUE value, VALUE ary)
1291 {
1292     if (key == Qundef) return ST_CONTINUE;
1293     rb_ary_push(ary, key);
1294     return ST_CONTINUE;
1295 }
1296 
1297 /*
1298  *  call-seq:
1299  *     hsh.keys    => array
1300  *
1301  *  Returns a new array populated with the keys from this hash. See also
1302  *  <code>Hash#values</code>.
1303  *
1304  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
1305  *     h.keys   #=> ["a", "b", "c", "d"]
1306  *
1307  */
1308 
1309 static VALUE
1310 rb_hash_keys(VALUE hash)
1311 {
1312     VALUE ary;
1313 
1314     ary = rb_ary_new();
1315     rb_hash_foreach(hash, keys_i, ary);
1316 
1317     return ary;
1318 }
1319 
1320 static int
1321 values_i(VALUE key, VALUE value, VALUE ary)
1322 {
1323     if (key == Qundef) return ST_CONTINUE;
1324     rb_ary_push(ary, value);
1325     return ST_CONTINUE;
1326 }
1327 
1328 /*
1329  *  call-seq:
1330  *     hsh.values    => array
1331  *
1332  *  Returns a new array populated with the values from <i>hsh</i>. See
1333  *  also <code>Hash#keys</code>.
1334  *
1335  *     h = { "a" => 100, "b" => 200, "c" => 300 }
1336  *     h.values   #=> [100, 200, 300]
1337  *
1338  */
1339 
1340 static VALUE
1341 rb_hash_values(VALUE hash)
1342 {
1343     VALUE ary;
1344 
1345     ary = rb_ary_new();
1346     rb_hash_foreach(hash, values_i, ary);
1347 
1348     return ary;
1349 }
1350 
1351 /*
1352  *  call-seq:
1353  *     hsh.has_key?(key)    => true or false
1354  *     hsh.include?(key)    => true or false
1355  *     hsh.key?(key)        => true or false
1356  *     hsh.member?(key)     => true or false
1357  *
1358  *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
1359  *
1360  *     h = { "a" => 100, "b" => 200 }
1361  *     h.has_key?("a")   #=> true
1362  *     h.has_key?("z")   #=> false
1363  *
1364  */
1365 
1366 static VALUE
1367 rb_hash_has_key(VALUE hash, VALUE key)
1368 {
1369     if (!RHASH(hash)->ntbl)
1370         return Qfalse;
1371     if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
1372         return Qtrue;
1373     }
1374     return Qfalse;
1375 }
1376 
1377 static int
1378 rb_hash_search_value(VALUE key, VALUE value, VALUE *data)
1379 {
1380     if (key == Qundef) return ST_CONTINUE;
1381     if (rb_equal(value, data[1])) {
1382         data[0] = Qtrue;
1383         return ST_STOP;
1384     }
1385     return ST_CONTINUE;
1386 }
1387 
1388 /*
1389  *  call-seq:
1390  *     hsh.has_value?(value)    => true or false
1391  *     hsh.value?(value)        => true or false
1392  *
1393  *  Returns <code>true</code> if the given value is present for some key
1394  *  in <i>hsh</i>.
1395  *
1396  *     h = { "a" => 100, "b" => 200 }
1397  *     h.has_value?(100)   #=> true
1398  *     h.has_value?(999)   #=> false
1399  */
1400 
1401 static VALUE
1402 rb_hash_has_value(VALUE hash, VALUE val)
1403 {
1404     VALUE data[2];
1405 
1406     data[0] = Qfalse;
1407     data[1] = val;
1408     rb_hash_foreach(hash, rb_hash_search_value, (st_data_t)data);
1409     return data[0];
1410 }
1411 
1412 struct equal_data {
1413     VALUE result;
1414     st_table *tbl;
1415     int eql;
1416 };
1417 
1418 static int
1419 eql_i(VALUE key, VALUE val1, struct equal_data *data)
1420 {
1421     VALUE val2;
1422 
1423     if (key == Qundef) return ST_CONTINUE;
1424     if (!st_lookup(data->tbl, key, &val2)) {
1425         data->result = Qfalse;
1426         return ST_STOP;
1427     }
1428     if (!(data->eql ? rb_eql(val1, val2) : rb_equal(val1, val2))) {
1429         data->result = Qfalse;
1430         return ST_STOP;
1431     }
1432     return ST_CONTINUE;
1433 }
1434 
1435 static VALUE
1436 recursive_eql(VALUE hash, VALUE dt, int recur)
1437 {
1438     struct equal_data *data;
1439 
1440     if (recur) return Qtrue;    /* Subtle! */
1441     data = (struct equal_data*)dt;
1442     data->result = Qtrue;
1443     rb_hash_foreach(hash, eql_i, (st_data_t)data);
1444 
1445     return data->result;
1446 }
1447 
1448 static VALUE
1449 hash_equal(VALUE hash1, VALUE hash2, int eql)
1450 {
1451     struct equal_data data;
1452 
1453     if (hash1 == hash2) return Qtrue;
1454     if (TYPE(hash2) != T_HASH) {
1455         if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
1456             return Qfalse;
1457         }
1458         if (eql)
1459             return rb_eql(hash2, hash1);
1460         else
1461             return rb_equal(hash2, hash1);
1462     }
1463     if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
1464         return Qfalse;
1465     if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
1466         return Qtrue;
1467     if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
1468         return Qfalse;
1469 #if 0
1470     if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) &&
1471           FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
1472         return Qfalse;
1473 #endif
1474 
1475     data.tbl = RHASH(hash2)->ntbl;
1476     data.eql = eql;
1477     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
1478 }
1479 
1480 /*
1481  *  call-seq:
1482  *     hsh == other_hash    => true or false
1483  *
1484  *  Equality---Two hashes are equal if they each contain the same number
1485  *  of keys and if each key-value pair is equal to (according to
1486  *  <code>Object#==</code>) the corresponding elements in the other
1487  *  hash.
1488  *
1489  *     h1 = { "a" => 1, "c" => 2 }
1490  *     h2 = { 7 => 35, "c" => 2, "a" => 1 }
1491  *     h3 = { "a" => 1, "c" => 2, 7 => 35 }
1492  *     h4 = { "a" => 1, "d" => 2, "f" => 35 }
1493  *     h1 == h2   #=> false
1494  *     h2 == h3   #=> true
1495  *     h3 == h4   #=> false
1496  *
1497  */
1498 
1499 static VALUE
1500 rb_hash_equal(VALUE hash1, VALUE hash2)
1501 {
1502     return hash_equal(hash1, hash2, Qfalse);
1503 }
1504 
1505 /*
1506  *  call-seq:
1507  *     hash.eql?(other)  -> true or false
1508  *
1509  *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are
1510  *  both hashes with the same content.
1511  */
1512 
1513 static VALUE
1514 rb_hash_eql(VALUE hash1, VALUE hash2)
1515 {
1516     return hash_equal(hash1, hash2, Qtrue);
1517 }
1518 
1519 static int
1520 hash_i(VALUE key, VALUE val, int *hval)
1521 {
1522     if (key == Qundef) return ST_CONTINUE;
1523     *hval ^= rb_hash(key);
1524     *hval ^= rb_hash(val);
1525     return ST_CONTINUE;
1526 }
1527 
1528 static VALUE
1529 recursive_hash(VALUE hash, VALUE dummy, int recur)
1530 {
1531     int hval;
1532 
1533     if (recur) {
1534         return LONG2FIX(0);
1535     }
1536     if (!RHASH(hash)->ntbl)
1537         return LONG2FIX(0);
1538     hval = RHASH(hash)->ntbl->num_entries;
1539     rb_hash_foreach(hash, hash_i, (st_data_t)&hval);
1540     return INT2FIX(hval);
1541 }
1542 
1543 /*
1544  *  call-seq:
1545  *     hsh.hash   -> fixnum
1546  *
1547  *  Compute a hash-code for this hash. Two hashes with the same content
1548  *  will have the same hash code (and will compare using <code>eql?</code>).
1549  */
1550 
1551 static VALUE
1552 rb_hash_hash(VALUE hash)
1553 {
1554     return rb_exec_recursive(recursive_hash, hash, 0);
1555 }
1556 
1557 static int
1558 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
1559 {
1560     if (key == Qundef) return ST_CONTINUE;
1561     rb_hash_aset(hash, value, key);
1562     return ST_CONTINUE;
1563 }
1564 
1565 /*
1566  *  call-seq:
1567  *     hsh.invert -> aHash
1568  *
1569  *  Returns a new hash created by using <i>hsh</i>'s values as keys, and
1570  *  the keys as values.
1571  *
1572  *     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
1573  *     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
1574  *
1575  */
1576 
1577 static VALUE
1578 rb_hash_invert(VALUE hash)
1579 {
1580     VALUE h = rb_hash_new();
1581 
1582     rb_hash_foreach(hash, rb_hash_invert_i, h);
1583     return h;
1584 }
1585 
1586 static int
1587 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
1588 {
1589     if (key == Qundef) return ST_CONTINUE;
1590     rb_hash_aset(hash, key, value);
1591     return ST_CONTINUE;
1592 }
1593 
1594 static int
1595 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
1596 {
1597     if (key == Qundef) return ST_CONTINUE;
1598     if (rb_hash_has_key(hash, key)) {
1599         value = rb_yield_values(3, key, rb_hash_aref(hash, key), value);
1600     }
1601     rb_hash_aset(hash, key, value);
1602     return ST_CONTINUE;
1603 }
1604 
1605 /*
1606  *  call-seq:
1607  *     hsh.merge!(other_hash)                                 => hsh
1608  *     hsh.update(other_hash)                                 => hsh
1609  *     hsh.merge!(other_hash){|key, oldval, newval| block}    => hsh
1610  *     hsh.update(other_hash){|key, oldval, newval| block}    => hsh
1611  *
1612  *  Adds the contents of <i>other_hash</i> to <i>hsh</i>.  If no
1613  *  block is specified entries with duplicate keys are overwritten
1614  *  with the values from <i>other_hash</i>, otherwise the value
1615  *  of each duplicate key is determined by calling the block with
1616  *  the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
1617  *
1618  *     h1 = { "a" => 100, "b" => 200 }
1619  *     h2 = { "b" => 254, "c" => 300 }
1620  *     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
1621  *
1622  *     h1 = { "a" => 100, "b" => 200 }
1623  *     h2 = { "b" => 254, "c" => 300 }
1624  *     h1.merge!(h2) { |key, v1, v2| v1 }
1625  *                     #=> {"a"=>100, "b"=>200, "c"=>300}
1626  */
1627 
1628 static VALUE
1629 rb_hash_update(VALUE hash1, VALUE hash2)
1630 {
1631     hash2 = to_hash(hash2);
1632     if (rb_block_given_p()) {
1633         rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
1634     }
1635     else {
1636         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
1637     }
1638     return hash1;
1639 }
1640 
1641 /*
1642  *  call-seq:
1643  *     hsh.merge(other_hash)                              -> a_hash
1644  *     hsh.merge(other_hash){|key, oldval, newval| block} -> a_hash
1645  *
1646  *  Returns a new hash containing the contents of <i>other_hash</i> and
1647  *  the contents of <i>hsh</i>, overwriting entries in <i>hsh</i> with
1648  *  duplicate keys with those from <i>other_hash</i>.
1649  *
1650  *     h1 = { "a" => 100, "b" => 200 }
1651  *     h2 = { "b" => 254, "c" => 300 }
1652  *     h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
1653  *     h1             #=> {"a"=>100, "b"=>200}
1654  *
1655  */
1656 
1657 static VALUE
1658 rb_hash_merge(VALUE hash1, VALUE hash2)
1659 {
1660     return rb_hash_update(rb_obj_dup(hash1), hash2);
1661 }
1662 
1663 static int
1664 assoc_i(VALUE key, VALUE val, VALUE *args)
1665 {
1666     if (key == Qundef) return ST_CONTINUE;
1667     if (RTEST(rb_equal(args[0], key))) {
1668         args[1] = rb_assoc_new(key, val);
1669         return ST_STOP;
1670     }
1671     return ST_CONTINUE;
1672 }
1673 
1674 /*
1675  *  call-seq:
1676  *     hash.assoc(obj)   ->  an_array  or  nil
1677  *
1678  *  Searches through the hash comparing _obj_ with the key using <code>==</code>.
1679  *  Returns the key-value pair (two elements array) or +nil+
1680  *  if no match is found.  See <code>Array#assoc</code>.
1681  *
1682  *     h = {"colors"  => ["red", "blue", "green"],
1683  *          "letters" => ["a", "b", "c" ]}
1684  *     h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
1685  *     h.assoc("foo")      #=> nil
1686  */
1687 
1688 VALUE
1689 rb_hash_assoc(VALUE hash, VALUE obj)
1690 {
1691     VALUE args[2];
1692 
1693     args[0] = obj;
1694     args[1] = Qnil;
1695     rb_hash_foreach(hash, assoc_i, (st_data_t)args);
1696     return args[1];
1697 }
1698 
1699 static int
1700 rassoc_i(VALUE key, VALUE val, VALUE *args)
1701 {
1702     if (key == Qundef) return ST_CONTINUE;
1703     if (RTEST(rb_equal(args[0], val))) {
1704         args[1] = rb_assoc_new(key, val);
1705         return ST_STOP;
1706     }
1707     return ST_CONTINUE;
1708 }
1709 
1710 /*
1711  *  call-seq:
1712  *     hash.rassoc(key) -> an_array or nil
1713  *
1714  *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
1715  *  Returns the first key-value pair (two elements array) that matches. See
1716  *  also <code>Array#rassoc</code>.
1717  *
1718  *     a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
1719  *     a.rassoc("two")    #=> [2, "two"]
1720  *     a.rassoc("four")   #=> nil
1721  */
1722 
1723 VALUE
1724 rb_hash_rassoc(VALUE hash, VALUE obj)
1725 {
1726     VALUE args[2];
1727 
1728     args[0] = obj;
1729     args[1] = Qnil;
1730     rb_hash_foreach(hash, rassoc_i, (st_data_t)args);
1731     return args[1];
1732 }
1733 
1734 /*
1735  *  call-seq:
1736  *     hash.flatten -> an_array
1737  *     hash.flatten(level) -> an_array
1738  *
1739  *  Returns a new array that is a one-dimensional flattening of this
1740  *  hash. That is, for every key or value that is an array, extract
1741  *  its elements into the new array.  Unlike Array#flatten, this
1742  *  method does not flatten recursively by default.  If the optional
1743  *  <i>level</i> argument determines the level of recursion to flatten.
1744  *
1745  *     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
1746  *     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
1747  *     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
1748  */
1749 
1750 static VALUE
1751 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
1752 {
1753     VALUE ary, tmp;
1754 
1755     ary = rb_hash_to_a(hash);
1756     if (argc == 0) {
1757         argc = 1;
1758         tmp = INT2FIX(1);
1759         argv = &tmp;
1760     }
1761     rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
1762     return ary;
1763 }
1764 
1765 /*
1766  *  call-seq:
1767  *     hsh.compare_by_identity => hsh
1768  *
1769  *  Makes <i>hsh</i> to compare its keys by their identity, i.e. it
1770  *  will consider exact same objects as same keys.
1771  *
1772  *     h1 = { "a" => 100, "b" => 200, :c => "c" }
1773  *     h1["a"]        #=> 100
1774  *     h1.compare_by_identity
1775  *     h1.compare_by_identity? #=> true
1776  *     h1["a"]        #=> nil  # different objects.
1777  *     h1[:c]         #=> "c"  # same symbols are all same.
1778  *
1779  */
1780 
1781 static VALUE
1782 rb_hash_compare_by_id(VALUE hash)
1783 {
1784     rb_hash_modify(hash);
1785     RHASH(hash)->ntbl->type = &identhash;
1786     rb_hash_rehash(hash);
1787     return hash;
1788 }
1789 
1790 /*
1791  *  call-seq:
1792  *     hsh.compare_by_identity? => true or false
1793  *
1794  *  Returns <code>true</code> if <i>hsh</i> will compare its keys by
1795  *  their identity.  Also see <code>Hash#compare_by_identity</code>.
1796  *
1797  */
1798 
1799 static VALUE
1800 rb_hash_compare_by_id_p(VALUE hash)
1801 {
1802     if (!RHASH(hash)->ntbl)
1803         return Qfalse;
1804     if (RHASH(hash)->ntbl->type == &identhash) {
1805         return Qtrue;
1806     }
1807     return Qfalse;
1808 }
1809 
1810 static int path_tainted = -1;
1811 
1812 static char **origenviron;
1813 #ifdef _WIN32
1814 #define GET_ENVIRON(e) (e = rb_w32_get_environ())
1815 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
1816 static char **my_environ;
1817 #undef environ
1818 #define environ my_environ
1819 #elif defined(__APPLE__)
1820 #undef environ
1821 #define environ (*_NSGetEnviron())
1822 #define GET_ENVIRON(e) (e)
1823 #define FREE_ENVIRON(e)
1824 #else
1825 extern char **environ;
1826 #define GET_ENVIRON(e) (e)
1827 #define FREE_ENVIRON(e)
1828 #endif
1829 #ifdef ENV_IGNORECASE
1830 #define ENVMATCH(s1, s2) (STRCASECMP(s1, s2) == 0)
1831 #define ENVNMATCH(s1, s2, n) (STRNCASECMP(s1, s2, n) == 0)
1832 #else
1833 #define ENVMATCH(n1, n2) (strcmp(n1, n2) == 0)
1834 #define ENVNMATCH(s1, s2, n) (memcmp(s1, s2, n) == 0)
1835 #endif
1836 
1837 static VALUE
1838 env_str_new(const char *ptr, long len)
1839 {
1840     VALUE str = rb_tainted_str_new(ptr, len);
1841 
1842     rb_obj_freeze(str);
1843     return str;
1844 }
1845 
1846 static VALUE
1847 env_str_new2(const char *ptr)
1848 {
1849     if (!ptr) return Qnil;
1850     return env_str_new(ptr, strlen(ptr));
1851 }
1852 
1853 static VALUE
1854 env_delete(VALUE obj, VALUE name)
1855 {
1856     char *nam, *val;
1857 
1858     rb_secure(4);
1859     SafeStringValue(name);
1860     nam = RSTRING_PTR(name);
1861     if (strlen(nam) != RSTRING_LEN(name)) {
1862         rb_raise(rb_eArgError, "bad environment variable name");
1863     }
1864     val = getenv(nam);
1865     if (val) {
1866         VALUE value = env_str_new2(val);
1867 
1868         ruby_setenv(nam, 0);
1869         if (ENVMATCH(nam, PATH_ENV)) {
1870             path_tainted = 0;
1871         }
1872         return value;
1873     }
1874     return Qnil;
1875 }
1876 
1877 static VALUE
1878 env_delete_m(VALUE obj, VALUE name)
1879 {
1880     VALUE val;
1881 
1882     val = env_delete(obj, name);
1883     if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
1884     return val;
1885 }
1886 
1887 static VALUE
1888 rb_f_getenv(VALUE obj, VALUE name)
1889 {
1890     char *nam, *env;
1891 
1892     rb_secure(4);
1893     SafeStringValue(name);
1894     nam = RSTRING_PTR(name);
1895     if (strlen(nam) != RSTRING_LEN(name)) {
1896         rb_raise(rb_eArgError, "bad environment variable name");
1897     }
1898     env = getenv(nam);
1899     if (env) {
1900         if (ENVMATCH(nam, PATH_ENV) && !rb_env_path_tainted()) {
1901             VALUE str = rb_str_new2(env);
1902 
1903             rb_obj_freeze(str);
1904             return str;
1905         }
1906         return env_str_new2(env);
1907     }
1908     return Qnil;
1909 }
1910 
1911 static VALUE
1912 env_fetch(int argc, VALUE *argv)
1913 {
1914     VALUE key, if_none;
1915     long block_given;
1916     char *nam, *env;
1917 
1918     rb_secure(4);
1919     rb_scan_args(argc, argv, "11", &key, &if_none);
1920     block_given = rb_block_given_p();
1921     if (block_given && argc == 2) {
1922         rb_warn("block supersedes default value argument");
1923     }
1924     SafeStringValue(key);
1925     nam = RSTRING_PTR(key);
1926     if (strlen(nam) != RSTRING_LEN(key)) {
1927         rb_raise(rb_eArgError, "bad environment variable name");
1928     }
1929     env = getenv(nam);
1930     if (!env) {
1931         if (block_given) return rb_yield(key);
1932         if (argc == 1) {
1933             rb_raise(rb_eKeyError, "key not found");
1934         }
1935         return if_none;
1936     }
1937     if (ENVMATCH(nam, PATH_ENV) && !rb_env_path_tainted())
1938         return rb_str_new2(env);
1939     return env_str_new2(env);
1940 }
1941 
1942 static void
1943 path_tainted_p(char *path)
1944 {
1945     path_tainted = rb_path_check(path)?0:1;
1946 }
1947 
1948 int
1949 rb_env_path_tainted(void)
1950 {
1951     if (path_tainted < 0) {
1952         path_tainted_p(getenv(PATH_ENV));
1953     }
1954     return path_tainted;
1955 }
1956 
1957 #if !defined(_WIN32) && !(defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
1958 static int
1959 envix(const char *nam)
1960 {
1961     register int i, len = strlen(nam);
1962     char **env;
1963 
1964     env = GET_ENVIRON(environ);
1965     for (i = 0; env[i]; i++) {
1966         if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
1967             break;                      /* memcmp must come first to avoid */
1968     }                                   /* potential SEGV's */
1969     FREE_ENVIRON(environ);
1970     return i;
1971 }
1972 #endif
1973 
1974 void
1975 ruby_setenv(const char *name, const char *value)
1976 {
1977 #if defined(_WIN32)
1978     /* The sane way to deal with the environment.
1979      * Has these advantages over putenv() & co.:
1980      *  * enables us to store a truly empty value in the
1981      *    environment (like in UNIX).
1982      *  * we don't have to deal with RTL globals, bugs and leaks.
1983      *  * Much faster.
1984      * Why you may want to enable USE_WIN32_RTL_ENV:
1985      *  * environ[] and RTL functions will not reflect changes,
1986      *    which might be an issue if extensions want to access
1987      *    the env. via RTL.  This cuts both ways, since RTL will
1988      *    not see changes made by extensions that call the Win32
1989      *    functions directly, either.
1990      * GSAR 97-06-07
1991      *
1992      * REMARK: USE_WIN32_RTL_ENV is already obsoleted since we don't use
1993      *         RTL's environ global variable directly yet.
1994      */
1995     SetEnvironmentVariable(name,value);
1996 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
1997 #undef setenv
1998 #undef unsetenv
1999     if (value)
2000         setenv(name,value,1);
2001     else
2002         unsetenv(name);
2003 #else  /* WIN32 */
2004     size_t len;
2005     int i=envix(name);                  /* where does it go? */
2006 
2007     if (environ == origenviron) {       /* need we copy environment? */
2008         int j;
2009         int max;
2010         char **tmpenv;
2011 
2012         for (max = i; environ[max]; max++) ;
2013         tmpenv = ALLOC_N(char*, max+2);
2014         for (j=0; j<max; j++)           /* copy environment */
2015             tmpenv[j] = strdup(environ[j]);
2016         tmpenv[max] = 0;
2017         environ = tmpenv;               /* tell exec where it is now */
2018     }
2019     if (environ[i]) {
2020         char **envp = origenviron;
2021         while (*envp && *envp != environ[i]) envp++;
2022         if (!*envp)
2023             xfree(environ[i]);
2024         if (!value) {
2025             while (environ[i]) {
2026                 environ[i] = environ[i+1];
2027                 i++;
2028             }
2029             return;
2030         }
2031     }
2032     else {                      /* does not exist yet */
2033         if (!value) return;
2034         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
2035         environ[i+1] = 0;       /* make sure it's null terminated */
2036     }
2037     len = strlen(name) + strlen(value) + 2;
2038     environ[i] = ALLOC_N(char, len);
2039     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
2040 #endif /* WIN32 */
2041 }
2042 
2043 void
2044 ruby_unsetenv(const char *name)
2045 {
2046     ruby_setenv(name, 0);
2047 }
2048 
2049 static VALUE
2050 env_aset(VALUE obj, VALUE nm, VALUE val)
2051 {
2052     char *name, *value;
2053 
2054     if (rb_safe_level() >= 4) {
2055         rb_raise(rb_eSecurityError, "can't change environment variable");
2056     }
2057 
2058     if (NIL_P(val)) {
2059         env_delete(obj, nm);
2060         return Qnil;
2061     }
2062     StringValue(nm);
2063     StringValue(val);
2064     name = RSTRING_PTR(nm);
2065     value = RSTRING_PTR(val);
2066     if (strlen(name) != RSTRING_LEN(nm))
2067         rb_raise(rb_eArgError, "bad environment variable name");
2068     if (strlen(value) != RSTRING_LEN(val))
2069         rb_raise(rb_eArgError, "bad environment variable value");
2070 
2071     ruby_setenv(name, value);
2072     if (ENVMATCH(name, PATH_ENV)) {
2073         if (OBJ_TAINTED(val)) {
2074             /* already tainted, no check */
2075             path_tainted = 1;
2076             return val;
2077         }
2078         else {
2079             path_tainted_p(value);
2080         }
2081     }
2082     return val;
2083 }
2084 
2085 static VALUE
2086 env_keys(void)
2087 {
2088     char **env;
2089     VALUE ary;
2090 
2091     rb_secure(4);
2092     ary = rb_ary_new();
2093     env = GET_ENVIRON(environ);
2094     while (*env) {
2095         char *s = strchr(*env, '=');
2096         if (s) {
2097             rb_ary_push(ary, env_str_new(*env, s-*env));
2098         }
2099         env++;
2100     }
2101     FREE_ENVIRON(environ);
2102     return ary;
2103 }
2104 
2105 static VALUE
2106 env_each_key(VALUE ehash)
2107 {
2108     VALUE keys;
2109     long i;
2110 
2111     RETURN_ENUMERATOR(ehash, 0, 0);
2112     keys = env_keys();  /* rb_secure(4); */
2113     for (i=0; i<RARRAY_LEN(keys); i++) {
2114         rb_yield(RARRAY_PTR(keys)[i]);
2115     }
2116     return ehash;
2117 }
2118 
2119 static VALUE
2120 env_values(void)
2121 {
2122     VALUE ary;
2123     char **env;
2124 
2125     rb_secure(4);
2126     ary = rb_ary_new();
2127     env = GET_ENVIRON(environ);
2128     while (*env) {
2129         char *s = strchr(*env, '=');
2130         if (s) {
2131             rb_ary_push(ary, env_str_new2(s+1));
2132         }
2133         env++;
2134     }
2135     FREE_ENVIRON(environ);
2136     return ary;
2137 }
2138 
2139 static VALUE
2140 env_each_value(VALUE ehash)
2141 {
2142     VALUE values;
2143     long i;
2144 
2145     RETURN_ENUMERATOR(ehash, 0, 0);
2146     values = env_values();      /* rb_secure(4); */
2147     for (i=0; i<RARRAY_LEN(values); i++) {
2148         rb_yield(RARRAY_PTR(values)[i]);
2149     }
2150     return ehash;
2151 }
2152 
2153 static VALUE
2154 env_each_pair(VALUE ehash)
2155 {
2156     char **env;
2157     VALUE ary;
2158     long i;
2159 
2160     RETURN_ENUMERATOR(ehash, 0, 0);
2161 
2162     rb_secure(4);
2163     ary = rb_ary_new();
2164     env = GET_ENVIRON(environ);
2165     while (*env) {
2166         char *s = strchr(*env, '=');
2167         if (s) {
2168             rb_ary_push(ary, env_str_new(*env, s-*env));
2169             rb_ary_push(ary, env_str_new2(s+1));
2170         }
2171         env++;
2172     }
2173     FREE_ENVIRON(environ);
2174 
2175     for (i=0; i<RARRAY_LEN(ary); i+=2) {
2176         rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]));
2177     }
2178     return ehash;
2179 }
2180 
2181 static VALUE
2182 env_reject_bang(VALUE ehash)
2183 {
2184     volatile VALUE keys;
2185     long i;
2186     int del = 0;
2187 
2188     RETURN_ENUMERATOR(ehash, 0, 0);
2189     keys = env_keys();  /* rb_secure(4); */
2190     for (i=0; i<RARRAY_LEN(keys); i++) {
2191         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
2192         if (!NIL_P(val)) {
2193             if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
2194                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
2195                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
2196                 del++;
2197             }
2198         }
2199     }
2200     if (del == 0) return Qnil;
2201     return envtbl;
2202 }
2203 
2204 static VALUE
2205 env_delete_if(VALUE ehash)
2206 {
2207     RETURN_ENUMERATOR(ehash, 0, 0);
2208     env_reject_bang(ehash);
2209     return envtbl;
2210 }
2211 
2212 static VALUE
2213 env_values_at(int argc, VALUE *argv)
2214 {
2215     VALUE result;
2216     long i;
2217 
2218     rb_secure(4);
2219     result = rb_ary_new();
2220     for (i=0; i<argc; i++) {
2221         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
2222     }
2223     return result;
2224 }
2225 
2226 static VALUE
2227 env_select(VALUE ehash)
2228 {
2229     VALUE result;
2230     char **env;
2231 
2232     RETURN_ENUMERATOR(ehash, 0, 0);
2233     rb_secure(4);
2234     result = rb_hash_new();
2235     env = GET_ENVIRON(environ);
2236     while (*env) {
2237         char *s = strchr(*env, '=');
2238         if (s) {
2239             VALUE k = env_str_new(*env, s-*env);
2240             VALUE v = env_str_new2(s+1);
2241             if (RTEST(rb_yield_values(2, k, v))) {
2242                 rb_hash_aset(result, k, v);
2243             }
2244         }
2245         env++;
2246     }
2247     FREE_ENVIRON(environ);
2248 
2249     return result;
2250 }
2251 
2252 VALUE
2253 rb_env_clear(void)
2254 {
2255     volatile VALUE keys;
2256     long i;
2257 
2258     keys = env_keys();  /* rb_secure(4); */
2259     for (i=0; i<RARRAY_LEN(keys); i++) {
2260         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
2261         if (!NIL_P(val)) {
2262             env_delete(Qnil, RARRAY_PTR(keys)[i]);
2263         }
2264     }
2265     return envtbl;
2266 }
2267 
2268 static VALUE
2269 env_to_s(void)
2270 {
2271     return rb_usascii_str_new2("ENV");
2272 }
2273 
2274 static VALUE
2275 env_inspect(void)
2276 {
2277     char **env;
2278     VALUE str, i;
2279 
2280     rb_secure(4);
2281     str = rb_str_buf_new2("{");
2282     env = GET_ENVIRON(environ);
2283     while (*env) {
2284         char *s = strchr(*env, '=');
2285 
2286         if (env != environ) {
2287             rb_str_buf_cat2(str, ", ");
2288         }
2289         if (s) {
2290             rb_str_buf_cat2(str, "\"");
2291             rb_str_buf_cat(str, *env, s-*env);
2292             rb_str_buf_cat2(str, "\"=>");
2293             i = rb_inspect(rb_str_new2(s+1));
2294             rb_str_buf_append(str, i);
2295         }
2296         env++;
2297     }
2298     FREE_ENVIRON(environ);
2299     rb_str_buf_cat2(str, "}");
2300     OBJ_TAINT(str);
2301 
2302     return str;
2303 }
2304 
2305 static VALUE
2306 env_to_a(void)
2307 {
2308     char **env;
2309     VALUE ary;
2310 
2311     rb_secure(4);
2312     ary = rb_ary_new();
2313     env = GET_ENVIRON(environ);
2314     while (*env) {
2315         char *s = strchr(*env, '=');
2316         if (s) {
2317             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
2318                                           env_str_new2(s+1)));
2319         }
2320         env++;
2321     }
2322     FREE_ENVIRON(environ);
2323     return ary;
2324 }
2325 
2326 static VALUE
2327 env_none(void)
2328 {
2329     return Qnil;
2330 }
2331 
2332 static VALUE
2333 env_size(void)
2334 {
2335     int i;
2336     char **env;
2337 
2338     rb_secure(4);
2339     env = GET_ENVIRON(environ);
2340     for(i=0; env[i]; i++)
2341         ;
2342     FREE_ENVIRON(environ);
2343     return INT2FIX(i);
2344 }
2345 
2346 static VALUE
2347 env_empty_p(void)
2348 {
2349     char **env;
2350 
2351     rb_secure(4);
2352     env = GET_ENVIRON(environ);
2353     if (env[0] == 0) {
2354         FREE_ENVIRON(environ);
2355         return Qtrue;
2356     }
2357     FREE_ENVIRON(environ);
2358     return Qfalse;
2359 }
2360 
2361 static VALUE
2362 env_has_key(VALUE env, VALUE key)
2363 {
2364     char *s;
2365 
2366     rb_secure(4);
2367     s = StringValuePtr(key);
2368     if (strlen(s) != RSTRING_LEN(key))
2369         rb_raise(rb_eArgError, "bad environment variable name");
2370     if (getenv(s)) return Qtrue;
2371     return Qfalse;
2372 }
2373 
2374 static VALUE
2375 env_assoc(VALUE env, VALUE key)
2376 {
2377     char *s, *e;
2378 
2379     rb_secure(4);
2380     s = StringValuePtr(key);
2381     if (strlen(s) != RSTRING_LEN(key))
2382         rb_raise(rb_eArgError, "bad environment variable name");
2383     e = getenv(s);
2384     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
2385     return Qnil;
2386 }
2387 
2388 static VALUE
2389 env_has_value(VALUE dmy, VALUE obj)
2390 {
2391     char **env;
2392 
2393     rb_secure(4);
2394     obj = rb_check_string_type(obj);
2395     if (NIL_P(obj)) return Qnil;
2396     env = GET_ENVIRON(environ);
2397     while (*env) {
2398         char *s = strchr(*env, '=');
2399         if (s++) {
2400             long len = strlen(s);
2401             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
2402                 FREE_ENVIRON(environ);
2403                 return Qtrue;
2404             }
2405         }
2406         env++;
2407     }
2408     FREE_ENVIRON(environ);
2409     return Qfalse;
2410 }
2411 
2412 static VALUE
2413 env_rassoc(VALUE dmy, VALUE obj)
2414 {
2415     char **env;
2416 
2417     rb_secure(4);
2418     obj = rb_check_string_type(obj);
2419     if (NIL_P(obj)) return Qnil;
2420     env = GET_ENVIRON(environ);
2421     while (*env) {
2422         char *s = strchr(*env, '=');
2423         if (s++) {
2424             long len = strlen(s);
2425             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
2426                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
2427                 FREE_ENVIRON(environ);
2428                 return result;
2429             }
2430         }
2431         env++;
2432     }
2433     FREE_ENVIRON(environ);
2434     return Qnil;
2435 }
2436 
2437 static VALUE
2438 env_key(VALUE dmy, VALUE value)
2439 {
2440     char **env;
2441     VALUE str;
2442 
2443     rb_secure(4);
2444     StringValue(value);
2445     env = GET_ENVIRON(environ);
2446     while (*env) {
2447         char *s = strchr(*env, '=');
2448         if (s++) {
2449             long len = strlen(s);
2450             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
2451                 str = env_str_new(*env, s-*env-1);
2452                 FREE_ENVIRON(environ);
2453                 return str;
2454             }
2455         }
2456         env++;
2457     }
2458     FREE_ENVIRON(environ);
2459     return Qnil;
2460 }
2461 
2462 static VALUE
2463 env_index(VALUE dmy, VALUE value)
2464 {
2465     rb_warn("ENV.index is deprecated; use ENV.key");
2466     return env_key(dmy, value);
2467 }
2468 
2469 static VALUE
2470 env_to_hash(void)
2471 {
2472     char **env;
2473     VALUE hash;
2474 
2475     rb_secure(4);
2476     hash = rb_hash_new();
2477     env = GET_ENVIRON(environ);
2478     while (*env) {
2479         char *s = strchr(*env, '=');
2480         if (s) {
2481             rb_hash_aset(hash, env_str_new(*env, s-*env),
2482                                env_str_new2(s+1));
2483         }
2484         env++;
2485     }
2486     FREE_ENVIRON(environ);
2487     return hash;
2488 }
2489 
2490 static VALUE
2491 env_reject(void)
2492 {
2493     return rb_hash_delete_if(env_to_hash());
2494 }
2495 
2496 static VALUE
2497 env_shift(void)
2498 {
2499     char **env;
2500 
2501     rb_secure(4);
2502     env = GET_ENVIRON(environ);
2503     if (*env) {
2504         char *s = strchr(*env, '=');
2505         if (s) {
2506             VALUE key = env_str_new(*env, s-*env);
2507             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
2508             env_delete(Qnil, key);
2509             return rb_assoc_new(key, val);
2510         }
2511     }
2512     FREE_ENVIRON(environ);
2513     return Qnil;
2514 }
2515 
2516 static VALUE
2517 env_invert(void)
2518 {
2519     return rb_hash_invert(env_to_hash());
2520 }
2521 
2522 static int
2523 env_replace_i(VALUE key, VALUE val, VALUE keys)
2524 {
2525     if (key != Qundef) {
2526         env_aset(Qnil, key, val);
2527         if (rb_ary_includes(keys, key)) {
2528             rb_ary_delete(keys, key);
2529         }
2530     }
2531     return ST_CONTINUE;
2532 }
2533 
2534 static VALUE
2535 env_replace(VALUE env, VALUE hash)
2536 {
2537     volatile VALUE keys;
2538     long i;
2539 
2540     keys = env_keys();  /* rb_secure(4); */
2541     if (env == hash) return env;
2542     hash = to_hash(hash);
2543     rb_hash_foreach(hash, env_replace_i, keys);
2544 
2545     for (i=0; i<RARRAY_LEN(keys); i++) {
2546         env_delete(env, RARRAY_PTR(keys)[i]);
2547     }
2548     return env;
2549 }
2550 
2551 static int
2552 env_update_i(VALUE key, VALUE val)
2553 {
2554     if (key != Qundef) {
2555         if (rb_block_given_p()) {
2556             val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
2557         }
2558         env_aset(Qnil, key, val);
2559     }
2560     return ST_CONTINUE;
2561 }
2562 
2563 static VALUE
2564 env_update(VALUE env, VALUE hash)
2565 {
2566     rb_secure(4);
2567     if (env == hash) return env;
2568     hash = to_hash(hash);
2569     rb_hash_foreach(hash, env_update_i, 0);
2570     return env;
2571 }
2572 
2573 /*
2574  *  A <code>Hash</code> is a collection of key-value pairs. It is
2575  *  similar to an <code>Array</code>, except that indexing is done via
2576  *  arbitrary keys of any object type, not an integer index. Hashes enumerate
2577  *  their values in the order that the corresponding keys were inserted.
2578  *
2579  *  Hashes have a <em>default value</em> that is returned when accessing
2580  *  keys that do not exist in the hash. By default, that value is
2581  *  <code>nil</code>.
2582  *
2583  */
2584 
2585 void
2586 Init_Hash(void)
2587 {
2588 #undef rb_intern
2589 #define rb_intern(str) rb_intern_const(str)
2590 
2591     id_hash = rb_intern("hash");
2592     id_yield = rb_intern("yield");
2593     id_default = rb_intern("default");
2594 
2595     rb_cHash = rb_define_class("Hash", rb_cObject);
2596 
2597     rb_include_module(rb_cHash, rb_mEnumerable);
2598 
2599     rb_define_alloc_func(rb_cHash, hash_alloc);
2600     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
2601     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
2602     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
2603     rb_define_method(rb_cHash,"initialize_copy", rb_hash_replace, 1);
2604     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
2605 
2606     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
2607     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
2608     rb_define_method(rb_cHash,"to_s", rb_hash_inspect, 0);
2609     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
2610 
2611     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
2612     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
2613     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
2614     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
2615     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
2616     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
2617     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
2618     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
2619     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
2620     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
2621     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
2622     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
2623     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
2624     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
2625     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
2626     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
2627 
2628     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
2629     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
2630     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
2631     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
2632 
2633     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
2634     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
2635     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
2636 
2637     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
2638     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
2639     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
2640     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
2641     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
2642     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
2643     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
2644     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
2645     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
2646     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
2647     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
2648     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
2649     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
2650     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
2651     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
2652 
2653     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
2654     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
2655     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
2656     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
2657     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
2658     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
2659 
2660     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
2661     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
2662 
2663     origenviron = environ;
2664     envtbl = rb_obj_alloc(rb_cObject);
2665     rb_extend_object(envtbl, rb_mEnumerable);
2666 
2667     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
2668     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
2669     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
2670     rb_define_singleton_method(envtbl,"store", env_aset, 2);
2671     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
2672     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
2673     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
2674     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
2675     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
2676     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
2677     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
2678     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
2679     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
2680     rb_define_singleton_method(envtbl,"select", env_select, 0);
2681     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
2682     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
2683     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
2684     rb_define_singleton_method(envtbl,"update", env_update, 1);
2685     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
2686     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
2687     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
2688     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
2689     rb_define_singleton_method(envtbl,"key", env_key, 1);
2690     rb_define_singleton_method(envtbl,"index", env_index, 1);
2691     rb_define_singleton_method(envtbl,"size", env_size, 0);
2692     rb_define_singleton_method(envtbl,"length", env_size, 0);
2693     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
2694     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
2695     rb_define_singleton_method(envtbl,"values", env_values, 0);
2696     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
2697     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
2698     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
2699     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
2700     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
2701     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
2702     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
2703     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
2704     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
2705     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
2706 
2707     rb_define_global_const("ENV", envtbl);
2708 }