Ruby  2.0.0p353(2013-11-22revision43784)
hash.c
Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   hash.c -
00004 
00005   $Author: nagachika $
00006   created at: Mon Nov 22 18:51:18 JST 1993
00007 
00008   Copyright (C) 1993-2007 Yukihiro Matsumoto
00009   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
00010   Copyright (C) 2000  Information-technology Promotion Agency, Japan
00011 
00012 **********************************************************************/
00013 
00014 #include "ruby/ruby.h"
00015 #include "ruby/st.h"
00016 #include "ruby/util.h"
00017 #include "ruby/encoding.h"
00018 #include "internal.h"
00019 #include <errno.h>
00020 #include "probes.h"
00021 
00022 #ifdef __APPLE__
00023 # ifdef HAVE_CRT_EXTERNS_H
00024 #  include <crt_externs.h>
00025 # else
00026 #  include "missing/crt_externs.h"
00027 # endif
00028 #endif
00029 
00030 static VALUE rb_hash_s_try_convert(VALUE, VALUE);
00031 
00032 #define HASH_DELETED  FL_USER1
00033 #define HASH_PROC_DEFAULT FL_USER2
00034 
00035 VALUE
00036 rb_hash_freeze(VALUE hash)
00037 {
00038     return rb_obj_freeze(hash);
00039 }
00040 
00041 VALUE rb_cHash;
00042 
00043 static VALUE envtbl;
00044 static ID id_hash, id_yield, id_default;
00045 
00046 static int
00047 rb_any_cmp(VALUE a, VALUE b)
00048 {
00049     if (a == b) return 0;
00050     if (FIXNUM_P(a) && FIXNUM_P(b)) {
00051         return a != b;
00052     }
00053     if (RB_TYPE_P(a, T_STRING) && RBASIC(a)->klass == rb_cString &&
00054         RB_TYPE_P(b, T_STRING) && RBASIC(b)->klass == rb_cString) {
00055         return rb_str_hash_cmp(a, b);
00056     }
00057     if (a == Qundef || b == Qundef) return -1;
00058     if (SYMBOL_P(a) && SYMBOL_P(b)) {
00059         return a != b;
00060     }
00061 
00062     return !rb_eql(a, b);
00063 }
00064 
00065 VALUE
00066 rb_hash(VALUE obj)
00067 {
00068     VALUE hval = rb_funcall(obj, id_hash, 0);
00069   retry:
00070     switch (TYPE(hval)) {
00071       case T_FIXNUM:
00072         return hval;
00073 
00074       case T_BIGNUM:
00075         return LONG2FIX(((long*)(RBIGNUM_DIGITS(hval)))[0]);
00076 
00077       default:
00078         hval = rb_to_int(hval);
00079         goto retry;
00080     }
00081 }
00082 
00083 static st_index_t
00084 rb_any_hash(VALUE a)
00085 {
00086     VALUE hval;
00087     st_index_t hnum;
00088 
00089     if (SPECIAL_CONST_P(a)) {
00090         if (a == Qundef) return 0;
00091         hnum = rb_hash_end(rb_hash_start((st_index_t)a));
00092     }
00093     else if (BUILTIN_TYPE(a) == T_STRING) {
00094         hnum = rb_str_hash(a);
00095     }
00096     else {
00097         hval = rb_hash(a);
00098         hnum = FIX2LONG(hval);
00099     }
00100     hnum <<= 1;
00101     return (st_index_t)RSHIFT(hnum, 1);
00102 }
00103 
00104 static const struct st_hash_type objhash = {
00105     rb_any_cmp,
00106     rb_any_hash,
00107 };
00108 
00109 extern const struct st_hash_type st_hashtype_num;
00110 #define identhash st_hashtype_num
00111 
00112 typedef int st_foreach_func(st_data_t, st_data_t, st_data_t);
00113 
00114 struct foreach_safe_arg {
00115     st_table *tbl;
00116     st_foreach_func *func;
00117     st_data_t arg;
00118 };
00119 
00120 static int
00121 foreach_safe_i(st_data_t key, st_data_t value, struct foreach_safe_arg *arg)
00122 {
00123     int status;
00124 
00125     status = (*arg->func)(key, value, arg->arg);
00126     if (status == ST_CONTINUE) {
00127         return ST_CHECK;
00128     }
00129     return status;
00130 }
00131 
00132 void
00133 st_foreach_safe(st_table *table, int (*func)(ANYARGS), st_data_t a)
00134 {
00135     struct foreach_safe_arg arg;
00136 
00137     arg.tbl = table;
00138     arg.func = (st_foreach_func *)func;
00139     arg.arg = a;
00140     if (st_foreach_check(table, foreach_safe_i, (st_data_t)&arg, 0)) {
00141         rb_raise(rb_eRuntimeError, "hash modified during iteration");
00142     }
00143 }
00144 
00145 typedef int rb_foreach_func(VALUE, VALUE, VALUE);
00146 
00147 struct hash_foreach_arg {
00148     VALUE hash;
00149     rb_foreach_func *func;
00150     VALUE arg;
00151 };
00152 
00153 static int
00154 hash_foreach_iter(st_data_t key, st_data_t value, st_data_t argp)
00155 {
00156     struct hash_foreach_arg *arg = (struct hash_foreach_arg *)argp;
00157     int status;
00158     st_table *tbl;
00159 
00160     tbl = RHASH(arg->hash)->ntbl;
00161     status = (*arg->func)((VALUE)key, (VALUE)value, arg->arg);
00162     if (RHASH(arg->hash)->ntbl != tbl) {
00163         rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
00164     }
00165     switch (status) {
00166       case ST_DELETE:
00167         FL_SET(arg->hash, HASH_DELETED);
00168         return ST_DELETE;
00169       case ST_CONTINUE:
00170         break;
00171       case ST_STOP:
00172         return ST_STOP;
00173     }
00174     return ST_CHECK;
00175 }
00176 
00177 static VALUE
00178 hash_foreach_ensure(VALUE hash)
00179 {
00180     if (--RHASH_ITER_LEV(hash) == 0) {
00181         if (FL_TEST(hash, HASH_DELETED)) {
00182             st_cleanup_safe(RHASH(hash)->ntbl, (st_data_t)Qundef);
00183             FL_UNSET(hash, HASH_DELETED);
00184         }
00185     }
00186     return 0;
00187 }
00188 
00189 static VALUE
00190 hash_foreach_call(VALUE arg)
00191 {
00192     VALUE hash = ((struct hash_foreach_arg *)arg)->hash;
00193     if (st_foreach_check(RHASH(hash)->ntbl, hash_foreach_iter, (st_data_t)arg, (st_data_t)Qundef)) {
00194         rb_raise(rb_eRuntimeError, "hash modified during iteration");
00195     }
00196     return Qnil;
00197 }
00198 
00199 void
00200 rb_hash_foreach(VALUE hash, int (*func)(ANYARGS), VALUE farg)
00201 {
00202     struct hash_foreach_arg arg;
00203 
00204     if (!RHASH(hash)->ntbl)
00205         return;
00206     RHASH_ITER_LEV(hash)++;
00207     arg.hash = hash;
00208     arg.func = (rb_foreach_func *)func;
00209     arg.arg  = farg;
00210     rb_ensure(hash_foreach_call, (VALUE)&arg, hash_foreach_ensure, hash);
00211 }
00212 
00213 static VALUE
00214 hash_alloc(VALUE klass)
00215 {
00216     NEWOBJ_OF(hash, struct RHash, klass, T_HASH);
00217 
00218     RHASH_IFNONE(hash) = Qnil;
00219 
00220     return (VALUE)hash;
00221 }
00222 
00223 static VALUE
00224 empty_hash_alloc(VALUE klass)
00225 {
00226     if (RUBY_DTRACE_HASH_CREATE_ENABLED()) {
00227         RUBY_DTRACE_HASH_CREATE(0, rb_sourcefile(), rb_sourceline());
00228     }
00229 
00230     return hash_alloc(klass);
00231 }
00232 
00233 VALUE
00234 rb_hash_new(void)
00235 {
00236     return hash_alloc(rb_cHash);
00237 }
00238 
00239 VALUE
00240 rb_hash_dup(VALUE hash)
00241 {
00242     NEWOBJ_OF(ret, struct RHash,
00243                 rb_obj_class(hash),
00244                 (RBASIC(hash)->flags)&(T_MASK|FL_EXIVAR|FL_TAINT|FL_UNTRUSTED));
00245     if (FL_TEST((hash), FL_EXIVAR))
00246         rb_copy_generic_ivar((VALUE)(ret),(VALUE)(hash));
00247 
00248     if (!RHASH_EMPTY_P(hash))
00249         ret->ntbl = st_copy(RHASH(hash)->ntbl);
00250     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00251         FL_SET(ret, HASH_PROC_DEFAULT);
00252     }
00253     RHASH_IFNONE(ret) = RHASH_IFNONE(hash);
00254     return (VALUE)ret;
00255 }
00256 
00257 static void
00258 rb_hash_modify_check(VALUE hash)
00259 {
00260     rb_check_frozen(hash);
00261     if (!OBJ_UNTRUSTED(hash) && rb_safe_level() >= 4)
00262         rb_raise(rb_eSecurityError, "Insecure: can't modify hash");
00263 }
00264 
00265 struct st_table *
00266 rb_hash_tbl(VALUE hash)
00267 {
00268     if (!RHASH(hash)->ntbl) {
00269         RHASH(hash)->ntbl = st_init_table(&objhash);
00270     }
00271     return RHASH(hash)->ntbl;
00272 }
00273 
00274 static void
00275 rb_hash_modify(VALUE hash)
00276 {
00277     rb_hash_modify_check(hash);
00278     rb_hash_tbl(hash);
00279 }
00280 
00281 NORETURN(static void no_new_key(void));
00282 static void
00283 no_new_key(void)
00284 {
00285     rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
00286 }
00287 
00288 #define NOINSERT_UPDATE_CALLBACK(func) \
00289 int \
00290 func##_noinsert(st_data_t *key, st_data_t *val, st_data_t arg, int existing) \
00291 { \
00292     if (!existing) no_new_key(); \
00293     return func(key, val, arg, existing); \
00294 }
00295 
00296 #define UPDATE_CALLBACK(iter_lev, func) ((iter_lev) > 0 ? func##_noinsert : func)
00297 
00298 #define RHASH_UPDATE_ITER(hash, iter_lev, key, func, arg) \
00299     st_update(RHASH(hash)->ntbl, (st_data_t)(key),        \
00300               UPDATE_CALLBACK((iter_lev), func),          \
00301               (st_data_t)(arg))
00302 #define RHASH_UPDATE(hash, key, func, arg) \
00303     RHASH_UPDATE_ITER(hash, RHASH_ITER_LEV(hash), key, func, arg)
00304 
00305 static void
00306 default_proc_arity_check(VALUE proc)
00307 {
00308     int n = rb_proc_arity(proc);
00309 
00310     if (rb_proc_lambda_p(proc) && n != 2 && (n >= 0 || n < -3)) {
00311         if (n < 0) n = -n-1;
00312         rb_raise(rb_eTypeError, "default_proc takes two arguments (2 for %d)", n);
00313     }
00314 }
00315 
00316 /*
00317  *  call-seq:
00318  *     Hash.new                          -> new_hash
00319  *     Hash.new(obj)                     -> new_hash
00320  *     Hash.new {|hash, key| block }     -> new_hash
00321  *
00322  *  Returns a new, empty hash. If this hash is subsequently accessed by
00323  *  a key that doesn't correspond to a hash entry, the value returned
00324  *  depends on the style of <code>new</code> used to create the hash. In
00325  *  the first form, the access returns <code>nil</code>. If
00326  *  <i>obj</i> is specified, this single object will be used for
00327  *  all <em>default values</em>. If a block is specified, it will be
00328  *  called with the hash object and the key, and should return the
00329  *  default value. It is the block's responsibility to store the value
00330  *  in the hash if required.
00331  *
00332  *     h = Hash.new("Go Fish")
00333  *     h["a"] = 100
00334  *     h["b"] = 200
00335  *     h["a"]           #=> 100
00336  *     h["c"]           #=> "Go Fish"
00337  *     # The following alters the single default object
00338  *     h["c"].upcase!   #=> "GO FISH"
00339  *     h["d"]           #=> "GO FISH"
00340  *     h.keys           #=> ["a", "b"]
00341  *
00342  *     # While this creates a new default object each time
00343  *     h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
00344  *     h["c"]           #=> "Go Fish: c"
00345  *     h["c"].upcase!   #=> "GO FISH: C"
00346  *     h["d"]           #=> "Go Fish: d"
00347  *     h.keys           #=> ["c", "d"]
00348  *
00349  */
00350 
00351 static VALUE
00352 rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
00353 {
00354     VALUE ifnone;
00355 
00356     rb_hash_modify(hash);
00357     if (rb_block_given_p()) {
00358         rb_check_arity(argc, 0, 0);
00359         ifnone = rb_block_proc();
00360         default_proc_arity_check(ifnone);
00361         RHASH_IFNONE(hash) = ifnone;
00362         FL_SET(hash, HASH_PROC_DEFAULT);
00363     }
00364     else {
00365         rb_scan_args(argc, argv, "01", &ifnone);
00366         RHASH_IFNONE(hash) = ifnone;
00367     }
00368 
00369     return hash;
00370 }
00371 
00372 /*
00373  *  call-seq:
00374  *     Hash[ key, value, ... ]         -> new_hash
00375  *     Hash[ [ [key, value], ... ] ]   -> new_hash
00376  *     Hash[ object ]                  -> new_hash
00377  *
00378  *  Creates a new hash populated with the given objects. Equivalent to
00379  *  the literal <code>{ <i>key</i> => <i>value</i>, ... }</code>. In the first
00380  *  form, keys and values occur in pairs, so there must be an even number of arguments.
00381  *  The second and third form take a single argument which is either
00382  *  an array of key-value pairs or an object convertible to a hash.
00383  *
00384  *     Hash["a", 100, "b", 200]             #=> {"a"=>100, "b"=>200}
00385  *     Hash[ [ ["a", 100], ["b", 200] ] ]   #=> {"a"=>100, "b"=>200}
00386  *     Hash["a" => 100, "b" => 200]         #=> {"a"=>100, "b"=>200}
00387  */
00388 
00389 static VALUE
00390 rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
00391 {
00392     VALUE hash, tmp;
00393     int i;
00394 
00395     if (argc == 1) {
00396         tmp = rb_hash_s_try_convert(Qnil, argv[0]);
00397         if (!NIL_P(tmp)) {
00398             hash = hash_alloc(klass);
00399             if (RHASH(tmp)->ntbl) {
00400                 RHASH(hash)->ntbl = st_copy(RHASH(tmp)->ntbl);
00401             }
00402             return hash;
00403         }
00404 
00405         tmp = rb_check_array_type(argv[0]);
00406         if (!NIL_P(tmp)) {
00407             long i;
00408 
00409             hash = hash_alloc(klass);
00410             for (i = 0; i < RARRAY_LEN(tmp); ++i) {
00411                 VALUE e = RARRAY_PTR(tmp)[i];
00412                 VALUE v = rb_check_array_type(e);
00413                 VALUE key, val = Qnil;
00414 
00415                 if (NIL_P(v)) {
00416 #if 0 /* refix in the next release */
00417                     rb_raise(rb_eArgError, "wrong element type %s at %ld (expected array)",
00418                              rb_builtin_class_name(e), i);
00419 
00420 #else
00421                     rb_warn("wrong element type %s at %ld (expected array)",
00422                             rb_builtin_class_name(e), i);
00423                     rb_warn("ignoring wrong elements is deprecated, remove them explicitly");
00424                     rb_warn("this causes ArgumentError in the next release");
00425                     continue;
00426 #endif
00427                 }
00428                 switch (RARRAY_LEN(v)) {
00429                   default:
00430                     rb_raise(rb_eArgError, "invalid number of elements (%ld for 1..2)",
00431                              RARRAY_LEN(v));
00432                   case 2:
00433                     val = RARRAY_PTR(v)[1];
00434                   case 1:
00435                     key = RARRAY_PTR(v)[0];
00436                     rb_hash_aset(hash, key, val);
00437                 }
00438             }
00439             return hash;
00440         }
00441     }
00442     if (argc % 2 != 0) {
00443         rb_raise(rb_eArgError, "odd number of arguments for Hash");
00444     }
00445 
00446     hash = hash_alloc(klass);
00447     for (i=0; i<argc; i+=2) {
00448         rb_hash_aset(hash, argv[i], argv[i + 1]);
00449     }
00450 
00451     return hash;
00452 }
00453 
00454 static VALUE
00455 to_hash(VALUE hash)
00456 {
00457     return rb_convert_type(hash, T_HASH, "Hash", "to_hash");
00458 }
00459 
00460 VALUE
00461 rb_check_hash_type(VALUE hash)
00462 {
00463     return rb_check_convert_type(hash, T_HASH, "Hash", "to_hash");
00464 }
00465 
00466 /*
00467  *  call-seq:
00468  *     Hash.try_convert(obj) -> hash or nil
00469  *
00470  *  Try to convert <i>obj</i> into a hash, using to_hash method.
00471  *  Returns converted hash or nil if <i>obj</i> cannot be converted
00472  *  for any reason.
00473  *
00474  *     Hash.try_convert({1=>2})   # => {1=>2}
00475  *     Hash.try_convert("1=>2")   # => nil
00476  */
00477 static VALUE
00478 rb_hash_s_try_convert(VALUE dummy, VALUE hash)
00479 {
00480     return rb_check_hash_type(hash);
00481 }
00482 
00483 static int
00484 rb_hash_rehash_i(VALUE key, VALUE value, VALUE arg)
00485 {
00486     st_table *tbl = (st_table *)arg;
00487 
00488     st_insert(tbl, (st_data_t)key, (st_data_t)value);
00489     return ST_CONTINUE;
00490 }
00491 
00492 /*
00493  *  call-seq:
00494  *     hsh.rehash -> hsh
00495  *
00496  *  Rebuilds the hash based on the current hash values for each key. If
00497  *  values of key objects have changed since they were inserted, this
00498  *  method will reindex <i>hsh</i>. If <code>Hash#rehash</code> is
00499  *  called while an iterator is traversing the hash, an
00500  *  <code>RuntimeError</code> will be raised in the iterator.
00501  *
00502  *     a = [ "a", "b" ]
00503  *     c = [ "c", "d" ]
00504  *     h = { a => 100, c => 300 }
00505  *     h[a]       #=> 100
00506  *     a[0] = "z"
00507  *     h[a]       #=> nil
00508  *     h.rehash   #=> {["z", "b"]=>100, ["c", "d"]=>300}
00509  *     h[a]       #=> 100
00510  */
00511 
00512 static VALUE
00513 rb_hash_rehash(VALUE hash)
00514 {
00515     st_table *tbl;
00516 
00517     if (RHASH_ITER_LEV(hash) > 0) {
00518         rb_raise(rb_eRuntimeError, "rehash during iteration");
00519     }
00520     rb_hash_modify_check(hash);
00521     if (!RHASH(hash)->ntbl)
00522         return hash;
00523     tbl = st_init_table_with_size(RHASH(hash)->ntbl->type, RHASH(hash)->ntbl->num_entries);
00524     rb_hash_foreach(hash, rb_hash_rehash_i, (VALUE)tbl);
00525     st_free_table(RHASH(hash)->ntbl);
00526     RHASH(hash)->ntbl = tbl;
00527 
00528     return hash;
00529 }
00530 
00531 static VALUE
00532 hash_default_value(VALUE hash, VALUE key)
00533 {
00534     if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) {
00535         VALUE ifnone = RHASH_IFNONE(hash);
00536         if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone;
00537         if (key == Qundef) return Qnil;
00538         return rb_funcall(ifnone, id_yield, 2, hash, key);
00539     }
00540     else {
00541         return rb_funcall(hash, id_default, 1, key);
00542     }
00543 }
00544 
00545 /*
00546  *  call-seq:
00547  *     hsh[key]    ->  value
00548  *
00549  *  Element Reference---Retrieves the <i>value</i> object corresponding
00550  *  to the <i>key</i> object. If not found, returns the default value (see
00551  *  <code>Hash::new</code> for details).
00552  *
00553  *     h = { "a" => 100, "b" => 200 }
00554  *     h["a"]   #=> 100
00555  *     h["c"]   #=> nil
00556  *
00557  */
00558 
00559 VALUE
00560 rb_hash_aref(VALUE hash, VALUE key)
00561 {
00562     st_data_t val;
00563 
00564     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00565         return hash_default_value(hash, key);
00566     }
00567     return (VALUE)val;
00568 }
00569 
00570 VALUE
00571 rb_hash_lookup2(VALUE hash, VALUE key, VALUE def)
00572 {
00573     st_data_t val;
00574 
00575     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00576         return def; /* without Hash#default */
00577     }
00578     return (VALUE)val;
00579 }
00580 
00581 VALUE
00582 rb_hash_lookup(VALUE hash, VALUE key)
00583 {
00584     return rb_hash_lookup2(hash, key, Qnil);
00585 }
00586 
00587 /*
00588  *  call-seq:
00589  *     hsh.fetch(key [, default] )       -> obj
00590  *     hsh.fetch(key) {| key | block }   -> obj
00591  *
00592  *  Returns a value from the hash for the given key. If the key can't be
00593  *  found, there are several options: With no other arguments, it will
00594  *  raise an <code>KeyError</code> exception; if <i>default</i> is
00595  *  given, then that will be returned; if the optional code block is
00596  *  specified, then that will be run and its result returned.
00597  *
00598  *     h = { "a" => 100, "b" => 200 }
00599  *     h.fetch("a")                            #=> 100
00600  *     h.fetch("z", "go fish")                 #=> "go fish"
00601  *     h.fetch("z") { |el| "go fish, #{el}"}   #=> "go fish, z"
00602  *
00603  *  The following example shows that an exception is raised if the key
00604  *  is not found and a default value is not supplied.
00605  *
00606  *     h = { "a" => 100, "b" => 200 }
00607  *     h.fetch("z")
00608  *
00609  *  <em>produces:</em>
00610  *
00611  *     prog.rb:2:in `fetch': key not found (KeyError)
00612  *      from prog.rb:2
00613  *
00614  */
00615 
00616 static VALUE
00617 rb_hash_fetch_m(int argc, VALUE *argv, VALUE hash)
00618 {
00619     VALUE key, if_none;
00620     st_data_t val;
00621     long block_given;
00622 
00623     rb_scan_args(argc, argv, "11", &key, &if_none);
00624 
00625     block_given = rb_block_given_p();
00626     if (block_given && argc == 2) {
00627         rb_warn("block supersedes default value argument");
00628     }
00629     if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) {
00630         if (block_given) return rb_yield(key);
00631         if (argc == 1) {
00632             volatile VALUE desc = rb_protect(rb_inspect, key, 0);
00633             if (NIL_P(desc)) {
00634                 desc = rb_any_to_s(key);
00635             }
00636             desc = rb_str_ellipsize(desc, 65);
00637             rb_raise(rb_eKeyError, "key not found: %s", RSTRING_PTR(desc));
00638         }
00639         return if_none;
00640     }
00641     return (VALUE)val;
00642 }
00643 
00644 VALUE
00645 rb_hash_fetch(VALUE hash, VALUE key)
00646 {
00647     return rb_hash_fetch_m(1, &key, hash);
00648 }
00649 
00650 /*
00651  *  call-seq:
00652  *     hsh.default(key=nil)   -> obj
00653  *
00654  *  Returns the default value, the value that would be returned by
00655  *  <i>hsh</i>[<i>key</i>] if <i>key</i> did not exist in <i>hsh</i>.
00656  *  See also <code>Hash::new</code> and <code>Hash#default=</code>.
00657  *
00658  *     h = Hash.new                            #=> {}
00659  *     h.default                               #=> nil
00660  *     h.default(2)                            #=> nil
00661  *
00662  *     h = Hash.new("cat")                     #=> {}
00663  *     h.default                               #=> "cat"
00664  *     h.default(2)                            #=> "cat"
00665  *
00666  *     h = Hash.new {|h,k| h[k] = k.to_i*10}   #=> {}
00667  *     h.default                               #=> nil
00668  *     h.default(2)                            #=> 20
00669  */
00670 
00671 static VALUE
00672 rb_hash_default(int argc, VALUE *argv, VALUE hash)
00673 {
00674     VALUE key, ifnone;
00675 
00676     rb_scan_args(argc, argv, "01", &key);
00677     ifnone = RHASH_IFNONE(hash);
00678     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00679         if (argc == 0) return Qnil;
00680         return rb_funcall(ifnone, id_yield, 2, hash, key);
00681     }
00682     return ifnone;
00683 }
00684 
00685 /*
00686  *  call-seq:
00687  *     hsh.default = obj     -> obj
00688  *
00689  *  Sets the default value, the value returned for a key that does not
00690  *  exist in the hash. It is not possible to set the default to a
00691  *  <code>Proc</code> that will be executed on each key lookup.
00692  *
00693  *     h = { "a" => 100, "b" => 200 }
00694  *     h.default = "Go fish"
00695  *     h["a"]     #=> 100
00696  *     h["z"]     #=> "Go fish"
00697  *     # This doesn't do what you might hope...
00698  *     h.default = proc do |hash, key|
00699  *       hash[key] = key + key
00700  *     end
00701  *     h[2]       #=> #<Proc:0x401b3948@-:6>
00702  *     h["cat"]   #=> #<Proc:0x401b3948@-:6>
00703  */
00704 
00705 static VALUE
00706 rb_hash_set_default(VALUE hash, VALUE ifnone)
00707 {
00708     rb_hash_modify_check(hash);
00709     RHASH_IFNONE(hash) = ifnone;
00710     FL_UNSET(hash, HASH_PROC_DEFAULT);
00711     return ifnone;
00712 }
00713 
00714 /*
00715  *  call-seq:
00716  *     hsh.default_proc -> anObject
00717  *
00718  *  If <code>Hash::new</code> was invoked with a block, return that
00719  *  block, otherwise return <code>nil</code>.
00720  *
00721  *     h = Hash.new {|h,k| h[k] = k*k }   #=> {}
00722  *     p = h.default_proc                 #=> #<Proc:0x401b3d08@-:1>
00723  *     a = []                             #=> []
00724  *     p.call(a, 2)
00725  *     a                                  #=> [nil, nil, 4]
00726  */
00727 
00728 
00729 static VALUE
00730 rb_hash_default_proc(VALUE hash)
00731 {
00732     if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
00733         return RHASH_IFNONE(hash);
00734     }
00735     return Qnil;
00736 }
00737 
00738 /*
00739  *  call-seq:
00740  *     hsh.default_proc = proc_obj or nil
00741  *
00742  *  Sets the default proc to be executed on each failed key lookup.
00743  *
00744  *     h.default_proc = proc do |hash, key|
00745  *       hash[key] = key + key
00746  *     end
00747  *     h[2]       #=> 4
00748  *     h["cat"]   #=> "catcat"
00749  */
00750 
00751 static VALUE
00752 rb_hash_set_default_proc(VALUE hash, VALUE proc)
00753 {
00754     VALUE b;
00755 
00756     rb_hash_modify_check(hash);
00757     if (NIL_P(proc)) {
00758         FL_UNSET(hash, HASH_PROC_DEFAULT);
00759         RHASH_IFNONE(hash) = proc;
00760         return proc;
00761     }
00762     b = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
00763     if (NIL_P(b) || !rb_obj_is_proc(b)) {
00764         rb_raise(rb_eTypeError,
00765                  "wrong default_proc type %s (expected Proc)",
00766                  rb_obj_classname(proc));
00767     }
00768     proc = b;
00769     default_proc_arity_check(proc);
00770     RHASH_IFNONE(hash) = proc;
00771     FL_SET(hash, HASH_PROC_DEFAULT);
00772     return proc;
00773 }
00774 
00775 static int
00776 key_i(VALUE key, VALUE value, VALUE arg)
00777 {
00778     VALUE *args = (VALUE *)arg;
00779 
00780     if (rb_equal(value, args[0])) {
00781         args[1] = key;
00782         return ST_STOP;
00783     }
00784     return ST_CONTINUE;
00785 }
00786 
00787 /*
00788  *  call-seq:
00789  *     hsh.key(value)    -> key
00790  *
00791  *  Returns the key of an occurrence of a given value. If the value is
00792  *  not found, returns <code>nil</code>.
00793  *
00794  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 300 }
00795  *     h.key(200)   #=> "b"
00796  *     h.key(300)   #=> "c"
00797  *     h.key(999)   #=> nil
00798  *
00799  */
00800 
00801 static VALUE
00802 rb_hash_key(VALUE hash, VALUE value)
00803 {
00804     VALUE args[2];
00805 
00806     args[0] = value;
00807     args[1] = Qnil;
00808 
00809     rb_hash_foreach(hash, key_i, (VALUE)args);
00810 
00811     return args[1];
00812 }
00813 
00814 /* :nodoc: */
00815 static VALUE
00816 rb_hash_index(VALUE hash, VALUE value)
00817 {
00818     rb_warn("Hash#index is deprecated; use Hash#key");
00819     return rb_hash_key(hash, value);
00820 }
00821 
00822 static VALUE
00823 rb_hash_delete_key(VALUE hash, VALUE key)
00824 {
00825     st_data_t ktmp = (st_data_t)key, val;
00826 
00827     if (!RHASH(hash)->ntbl)
00828         return Qundef;
00829     if (RHASH_ITER_LEV(hash) > 0) {
00830         if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef)) {
00831             FL_SET(hash, HASH_DELETED);
00832             return (VALUE)val;
00833         }
00834     }
00835     else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
00836         return (VALUE)val;
00837     return Qundef;
00838 }
00839 
00840 /*
00841  *  call-seq:
00842  *     hsh.delete(key)                   -> value
00843  *     hsh.delete(key) {| key | block }  -> value
00844  *
00845  *  Deletes the key-value pair and returns the value from <i>hsh</i> whose
00846  *  key is equal to <i>key</i>. If the key is not found, returns the
00847  *  <em>default value</em>. If the optional code block is given and the
00848  *  key is not found, pass in the key and return the result of
00849  *  <i>block</i>.
00850  *
00851  *     h = { "a" => 100, "b" => 200 }
00852  *     h.delete("a")                              #=> 100
00853  *     h.delete("z")                              #=> nil
00854  *     h.delete("z") { |el| "#{el} not found" }   #=> "z not found"
00855  *
00856  */
00857 
00858 VALUE
00859 rb_hash_delete(VALUE hash, VALUE key)
00860 {
00861     VALUE val;
00862 
00863     rb_hash_modify_check(hash);
00864     val = rb_hash_delete_key(hash, key);
00865     if (val != Qundef) return val;
00866     if (rb_block_given_p()) {
00867         return rb_yield(key);
00868     }
00869     return Qnil;
00870 }
00871 
00872 struct shift_var {
00873     VALUE key;
00874     VALUE val;
00875 };
00876 
00877 static int
00878 shift_i(VALUE key, VALUE value, VALUE arg)
00879 {
00880     struct shift_var *var = (struct shift_var *)arg;
00881 
00882     if (var->key != Qundef) return ST_STOP;
00883     var->key = key;
00884     var->val = value;
00885     return ST_DELETE;
00886 }
00887 
00888 static int
00889 shift_i_safe(VALUE key, VALUE value, VALUE arg)
00890 {
00891     struct shift_var *var = (struct shift_var *)arg;
00892 
00893     var->key = key;
00894     var->val = value;
00895     return ST_STOP;
00896 }
00897 
00898 /*
00899  *  call-seq:
00900  *     hsh.shift -> anArray or obj
00901  *
00902  *  Removes a key-value pair from <i>hsh</i> and returns it as the
00903  *  two-item array <code>[</code> <i>key, value</i> <code>]</code>, or
00904  *  the hash's default value if the hash is empty.
00905  *
00906  *     h = { 1 => "a", 2 => "b", 3 => "c" }
00907  *     h.shift   #=> [1, "a"]
00908  *     h         #=> {2=>"b", 3=>"c"}
00909  */
00910 
00911 static VALUE
00912 rb_hash_shift(VALUE hash)
00913 {
00914     struct shift_var var;
00915 
00916     rb_hash_modify_check(hash);
00917     if (RHASH(hash)->ntbl) {
00918         var.key = Qundef;
00919         rb_hash_foreach(hash, RHASH_ITER_LEV(hash) > 0 ? shift_i_safe : shift_i,
00920                         (VALUE)&var);
00921 
00922         if (var.key != Qundef) {
00923             if (RHASH_ITER_LEV(hash) > 0) {
00924                 rb_hash_delete_key(hash, var.key);
00925             }
00926             return rb_assoc_new(var.key, var.val);
00927         }
00928     }
00929     return hash_default_value(hash, Qnil);
00930 }
00931 
00932 static int
00933 delete_if_i(VALUE key, VALUE value, VALUE hash)
00934 {
00935     if (RTEST(rb_yield_values(2, key, value))) {
00936         rb_hash_delete_key(hash, key);
00937     }
00938     return ST_CONTINUE;
00939 }
00940 
00941 static VALUE rb_hash_size(VALUE hash);
00942 
00943 /*
00944  *  call-seq:
00945  *     hsh.delete_if {| key, value | block }  -> hsh
00946  *     hsh.delete_if                          -> an_enumerator
00947  *
00948  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
00949  *  evaluates to <code>true</code>.
00950  *
00951  *  If no block is given, an enumerator is returned instead.
00952  *
00953  *     h = { "a" => 100, "b" => 200, "c" => 300 }
00954  *     h.delete_if {|key, value| key >= "b" }   #=> {"a"=>100}
00955  *
00956  */
00957 
00958 VALUE
00959 rb_hash_delete_if(VALUE hash)
00960 {
00961     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
00962     rb_hash_modify_check(hash);
00963     if (RHASH(hash)->ntbl)
00964         rb_hash_foreach(hash, delete_if_i, hash);
00965     return hash;
00966 }
00967 
00968 /*
00969  *  call-seq:
00970  *     hsh.reject! {| key, value | block }  -> hsh or nil
00971  *     hsh.reject!                          -> an_enumerator
00972  *
00973  *  Equivalent to <code>Hash#delete_if</code>, but returns
00974  *  <code>nil</code> if no changes were made.
00975  */
00976 
00977 VALUE
00978 rb_hash_reject_bang(VALUE hash)
00979 {
00980     st_index_t n;
00981 
00982     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
00983     rb_hash_modify(hash);
00984     if (!RHASH(hash)->ntbl)
00985         return Qnil;
00986     n = RHASH(hash)->ntbl->num_entries;
00987     rb_hash_foreach(hash, delete_if_i, hash);
00988     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
00989     return hash;
00990 }
00991 
00992 /*
00993  *  call-seq:
00994  *     hsh.reject {| key, value | block }  -> a_hash
00995  *     hsh.reject                          -> an_enumerator
00996  *
00997  *  Same as <code>Hash#delete_if</code>, but works on (and returns) a
00998  *  copy of the <i>hsh</i>. Equivalent to
00999  *  <code><i>hsh</i>.dup.delete_if</code>.
01000  *
01001  */
01002 
01003 static VALUE
01004 rb_hash_reject(VALUE hash)
01005 {
01006     return rb_hash_delete_if(rb_obj_dup(hash));
01007 }
01008 
01009 /*
01010  * call-seq:
01011  *   hsh.values_at(key, ...)   -> array
01012  *
01013  * Return an array containing the values associated with the given keys.
01014  * Also see <code>Hash.select</code>.
01015  *
01016  *   h = { "cat" => "feline", "dog" => "canine", "cow" => "bovine" }
01017  *   h.values_at("cow", "cat")  #=> ["bovine", "feline"]
01018  */
01019 
01020 VALUE
01021 rb_hash_values_at(int argc, VALUE *argv, VALUE hash)
01022 {
01023     VALUE result = rb_ary_new2(argc);
01024     long i;
01025 
01026     for (i=0; i<argc; i++) {
01027         rb_ary_push(result, rb_hash_aref(hash, argv[i]));
01028     }
01029     return result;
01030 }
01031 
01032 static int
01033 select_i(VALUE key, VALUE value, VALUE result)
01034 {
01035     if (RTEST(rb_yield_values(2, key, value)))
01036         rb_hash_aset(result, key, value);
01037     return ST_CONTINUE;
01038 }
01039 
01040 /*
01041  *  call-seq:
01042  *     hsh.select {|key, value| block}   -> a_hash
01043  *     hsh.select                        -> an_enumerator
01044  *
01045  *  Returns a new hash consisting of entries for which the block returns true.
01046  *
01047  *  If no block is given, an enumerator is returned instead.
01048  *
01049  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01050  *     h.select {|k,v| k > "a"}  #=> {"b" => 200, "c" => 300}
01051  *     h.select {|k,v| v < 200}  #=> {"a" => 100}
01052  */
01053 
01054 VALUE
01055 rb_hash_select(VALUE hash)
01056 {
01057     VALUE result;
01058 
01059     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01060     result = rb_hash_new();
01061     rb_hash_foreach(hash, select_i, result);
01062     return result;
01063 }
01064 
01065 static int
01066 keep_if_i(VALUE key, VALUE value, VALUE hash)
01067 {
01068     if (!RTEST(rb_yield_values(2, key, value))) {
01069         return ST_DELETE;
01070     }
01071     return ST_CONTINUE;
01072 }
01073 
01074 /*
01075  *  call-seq:
01076  *     hsh.select! {| key, value | block }  -> hsh or nil
01077  *     hsh.select!                          -> an_enumerator
01078  *
01079  *  Equivalent to <code>Hash#keep_if</code>, but returns
01080  *  <code>nil</code> if no changes were made.
01081  */
01082 
01083 VALUE
01084 rb_hash_select_bang(VALUE hash)
01085 {
01086     st_index_t n;
01087 
01088     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01089     rb_hash_modify_check(hash);
01090     if (!RHASH(hash)->ntbl)
01091         return Qnil;
01092     n = RHASH(hash)->ntbl->num_entries;
01093     rb_hash_foreach(hash, keep_if_i, hash);
01094     if (n == RHASH(hash)->ntbl->num_entries) return Qnil;
01095     return hash;
01096 }
01097 
01098 /*
01099  *  call-seq:
01100  *     hsh.keep_if {| key, value | block }  -> hsh
01101  *     hsh.keep_if                          -> an_enumerator
01102  *
01103  *  Deletes every key-value pair from <i>hsh</i> for which <i>block</i>
01104  *  evaluates to false.
01105  *
01106  *  If no block is given, an enumerator is returned instead.
01107  *
01108  */
01109 
01110 VALUE
01111 rb_hash_keep_if(VALUE hash)
01112 {
01113     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01114     rb_hash_modify_check(hash);
01115     if (RHASH(hash)->ntbl)
01116         rb_hash_foreach(hash, keep_if_i, hash);
01117     return hash;
01118 }
01119 
01120 static int
01121 clear_i(VALUE key, VALUE value, VALUE dummy)
01122 {
01123     return ST_DELETE;
01124 }
01125 
01126 /*
01127  *  call-seq:
01128  *     hsh.clear -> hsh
01129  *
01130  *  Removes all key-value pairs from <i>hsh</i>.
01131  *
01132  *     h = { "a" => 100, "b" => 200 }   #=> {"a"=>100, "b"=>200}
01133  *     h.clear                          #=> {}
01134  *
01135  */
01136 
01137 VALUE
01138 rb_hash_clear(VALUE hash)
01139 {
01140     rb_hash_modify_check(hash);
01141     if (!RHASH(hash)->ntbl)
01142         return hash;
01143     if (RHASH(hash)->ntbl->num_entries > 0) {
01144         if (RHASH_ITER_LEV(hash) > 0)
01145             rb_hash_foreach(hash, clear_i, 0);
01146         else
01147             st_clear(RHASH(hash)->ntbl);
01148     }
01149 
01150     return hash;
01151 }
01152 
01153 static int
01154 hash_aset(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
01155 {
01156     *val = arg;
01157     return ST_CONTINUE;
01158 }
01159 
01160 static int
01161 hash_aset_str(st_data_t *key, st_data_t *val, st_data_t arg, int existing)
01162 {
01163     *key = (st_data_t)rb_str_new_frozen((VALUE)*key);
01164     return hash_aset(key, val, arg, existing);
01165 }
01166 
01167 static NOINSERT_UPDATE_CALLBACK(hash_aset)
01168 static NOINSERT_UPDATE_CALLBACK(hash_aset_str)
01169 
01170 /*
01171  *  call-seq:
01172  *     hsh[key] = value        -> value
01173  *     hsh.store(key, value)   -> value
01174  *
01175  *  == Element Assignment
01176  *
01177  *  Associates the value given by +value+ with the key given by +key+.
01178  *
01179  *     h = { "a" => 100, "b" => 200 }
01180  *     h["a"] = 9
01181  *     h["c"] = 4
01182  *     h   #=> {"a"=>9, "b"=>200, "c"=>4}
01183  *
01184  *  +key+ should not have its value changed while it is in use as a key (an
01185  *  <tt>unfrozen String</tt> passed as a key will be duplicated and frozen).
01186  *
01187  *     a = "a"
01188  *     b = "b".freeze
01189  *     h = { a => 100, b => 200 }
01190  *     h.key(100).equal? a #=> false
01191  *     h.key(200).equal? b #=> true
01192  *
01193  */
01194 
01195 VALUE
01196 rb_hash_aset(VALUE hash, VALUE key, VALUE val)
01197 {
01198     int iter_lev = RHASH_ITER_LEV(hash);
01199     st_table *tbl = RHASH(hash)->ntbl;
01200 
01201     rb_hash_modify(hash);
01202     if (!tbl) {
01203         if (iter_lev > 0) no_new_key();
01204         tbl = RHASH_TBL(hash);
01205     }
01206     if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
01207         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
01208     }
01209     else {
01210         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
01211     }
01212     return val;
01213 }
01214 
01215 static int
01216 replace_i(VALUE key, VALUE val, VALUE hash)
01217 {
01218     rb_hash_aset(hash, key, val);
01219 
01220     return ST_CONTINUE;
01221 }
01222 
01223 static VALUE
01224 rb_hash_initialize_copy(VALUE hash, VALUE hash2)
01225 {
01226     rb_hash_modify_check(hash);
01227     hash2 = to_hash(hash2);
01228 
01229     Check_Type(hash2, T_HASH);
01230 
01231     if (!RHASH_EMPTY_P(hash2)) {
01232         RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl);
01233         rb_hash_rehash(hash);
01234     }
01235 
01236     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
01237         FL_SET(hash, HASH_PROC_DEFAULT);
01238     }
01239     else {
01240         FL_UNSET(hash, HASH_PROC_DEFAULT);
01241     }
01242     RHASH_IFNONE(hash) = RHASH_IFNONE(hash2);
01243 
01244     return hash;
01245 }
01246 
01247 /*
01248  *  call-seq:
01249  *     hsh.replace(other_hash) -> hsh
01250  *
01251  *  Replaces the contents of <i>hsh</i> with the contents of
01252  *  <i>other_hash</i>.
01253  *
01254  *     h = { "a" => 100, "b" => 200 }
01255  *     h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
01256  *
01257  */
01258 
01259 static VALUE
01260 rb_hash_replace(VALUE hash, VALUE hash2)
01261 {
01262     rb_hash_modify_check(hash);
01263     hash2 = to_hash(hash2);
01264     if (hash == hash2) return hash;
01265     rb_hash_clear(hash);
01266     if (RHASH(hash2)->ntbl) {
01267         rb_hash_tbl(hash);
01268         RHASH(hash)->ntbl->type = RHASH(hash2)->ntbl->type;
01269     }
01270     rb_hash_foreach(hash2, replace_i, hash);
01271     RHASH_IFNONE(hash) = RHASH_IFNONE(hash2);
01272     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
01273         FL_SET(hash, HASH_PROC_DEFAULT);
01274     }
01275     else {
01276         FL_UNSET(hash, HASH_PROC_DEFAULT);
01277     }
01278 
01279     return hash;
01280 }
01281 
01282 /*
01283  *  call-seq:
01284  *     hsh.length    ->  fixnum
01285  *     hsh.size      ->  fixnum
01286  *
01287  *  Returns the number of key-value pairs in the hash.
01288  *
01289  *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
01290  *     h.length        #=> 4
01291  *     h.delete("a")   #=> 200
01292  *     h.length        #=> 3
01293  */
01294 
01295 static VALUE
01296 rb_hash_size(VALUE hash)
01297 {
01298     if (!RHASH(hash)->ntbl)
01299         return INT2FIX(0);
01300     return INT2FIX(RHASH(hash)->ntbl->num_entries);
01301 }
01302 
01303 
01304 /*
01305  *  call-seq:
01306  *     hsh.empty?    -> true or false
01307  *
01308  *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
01309  *
01310  *     {}.empty?   #=> true
01311  *
01312  */
01313 
01314 static VALUE
01315 rb_hash_empty_p(VALUE hash)
01316 {
01317     return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
01318 }
01319 
01320 static int
01321 each_value_i(VALUE key, VALUE value)
01322 {
01323     rb_yield(value);
01324     return ST_CONTINUE;
01325 }
01326 
01327 /*
01328  *  call-seq:
01329  *     hsh.each_value {| value | block } -> hsh
01330  *     hsh.each_value                    -> an_enumerator
01331  *
01332  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the
01333  *  value as a parameter.
01334  *
01335  *  If no block is given, an enumerator is returned instead.
01336  *
01337  *     h = { "a" => 100, "b" => 200 }
01338  *     h.each_value {|value| puts value }
01339  *
01340  *  <em>produces:</em>
01341  *
01342  *     100
01343  *     200
01344  */
01345 
01346 static VALUE
01347 rb_hash_each_value(VALUE hash)
01348 {
01349     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01350     rb_hash_foreach(hash, each_value_i, 0);
01351     return hash;
01352 }
01353 
01354 static int
01355 each_key_i(VALUE key, VALUE value)
01356 {
01357     rb_yield(key);
01358     return ST_CONTINUE;
01359 }
01360 
01361 /*
01362  *  call-seq:
01363  *     hsh.each_key {| key | block } -> hsh
01364  *     hsh.each_key                  -> an_enumerator
01365  *
01366  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
01367  *  as a parameter.
01368  *
01369  *  If no block is given, an enumerator is returned instead.
01370  *
01371  *     h = { "a" => 100, "b" => 200 }
01372  *     h.each_key {|key| puts key }
01373  *
01374  *  <em>produces:</em>
01375  *
01376  *     a
01377  *     b
01378  */
01379 static VALUE
01380 rb_hash_each_key(VALUE hash)
01381 {
01382     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01383     rb_hash_foreach(hash, each_key_i, 0);
01384     return hash;
01385 }
01386 
01387 static int
01388 each_pair_i(VALUE key, VALUE value)
01389 {
01390     rb_yield(rb_assoc_new(key, value));
01391     return ST_CONTINUE;
01392 }
01393 
01394 /*
01395  *  call-seq:
01396  *     hsh.each      {| key, value | block } -> hsh
01397  *     hsh.each_pair {| key, value | block } -> hsh
01398  *     hsh.each                              -> an_enumerator
01399  *     hsh.each_pair                         -> an_enumerator
01400  *
01401  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
01402  *  pair as parameters.
01403  *
01404  *  If no block is given, an enumerator is returned instead.
01405  *
01406  *     h = { "a" => 100, "b" => 200 }
01407  *     h.each {|key, value| puts "#{key} is #{value}" }
01408  *
01409  *  <em>produces:</em>
01410  *
01411  *     a is 100
01412  *     b is 200
01413  *
01414  */
01415 
01416 static VALUE
01417 rb_hash_each_pair(VALUE hash)
01418 {
01419     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01420     rb_hash_foreach(hash, each_pair_i, 0);
01421     return hash;
01422 }
01423 
01424 static int
01425 to_a_i(VALUE key, VALUE value, VALUE ary)
01426 {
01427     rb_ary_push(ary, rb_assoc_new(key, value));
01428     return ST_CONTINUE;
01429 }
01430 
01431 /*
01432  *  call-seq:
01433  *     hsh.to_a -> array
01434  *
01435  *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
01436  *  value</i> <code>]</code> arrays.
01437  *
01438  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01439  *     h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
01440  */
01441 
01442 static VALUE
01443 rb_hash_to_a(VALUE hash)
01444 {
01445     VALUE ary;
01446 
01447     ary = rb_ary_new();
01448     rb_hash_foreach(hash, to_a_i, ary);
01449     OBJ_INFECT(ary, hash);
01450 
01451     return ary;
01452 }
01453 
01454 static int
01455 inspect_i(VALUE key, VALUE value, VALUE str)
01456 {
01457     VALUE str2;
01458 
01459     str2 = rb_inspect(key);
01460     if (RSTRING_LEN(str) > 1) {
01461         rb_str_buf_cat_ascii(str, ", ");
01462     }
01463     else {
01464         rb_enc_copy(str, str2);
01465     }
01466     rb_str_buf_append(str, str2);
01467     OBJ_INFECT(str, str2);
01468     rb_str_buf_cat_ascii(str, "=>");
01469     str2 = rb_inspect(value);
01470     rb_str_buf_append(str, str2);
01471     OBJ_INFECT(str, str2);
01472 
01473     return ST_CONTINUE;
01474 }
01475 
01476 static VALUE
01477 inspect_hash(VALUE hash, VALUE dummy, int recur)
01478 {
01479     VALUE str;
01480 
01481     if (recur) return rb_usascii_str_new2("{...}");
01482     str = rb_str_buf_new2("{");
01483     rb_hash_foreach(hash, inspect_i, str);
01484     rb_str_buf_cat2(str, "}");
01485     OBJ_INFECT(str, hash);
01486 
01487     return str;
01488 }
01489 
01490 /*
01491  * call-seq:
01492  *   hsh.to_s     -> string
01493  *   hsh.inspect  -> string
01494  *
01495  * Return the contents of this hash as a string.
01496  *
01497  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01498  *     h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
01499  */
01500 
01501 static VALUE
01502 rb_hash_inspect(VALUE hash)
01503 {
01504     if (RHASH_EMPTY_P(hash))
01505         return rb_usascii_str_new2("{}");
01506     return rb_exec_recursive(inspect_hash, hash, 0);
01507 }
01508 
01509 /*
01510  * call-seq:
01511  *    hsh.to_hash   => hsh
01512  *
01513  * Returns +self+.
01514  */
01515 
01516 static VALUE
01517 rb_hash_to_hash(VALUE hash)
01518 {
01519     return hash;
01520 }
01521 
01522 /*
01523  *  call-seq:
01524  *     hsh.to_h     -> hsh or new_hash
01525  *
01526  *  Returns +self+. If called on a subclass of Hash, converts
01527  *  the receiver to a Hash object.
01528  */
01529 
01530 static VALUE
01531 rb_hash_to_h(VALUE hash)
01532 {
01533     if (rb_obj_class(hash) != rb_cHash) {
01534         VALUE ret = rb_hash_new();
01535         if (!RHASH_EMPTY_P(hash))
01536             RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
01537         if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
01538             FL_SET(ret, HASH_PROC_DEFAULT);
01539         }
01540         RHASH_IFNONE(ret) = RHASH_IFNONE(hash);
01541         return ret;
01542     }
01543     return hash;
01544 }
01545 
01546 static int
01547 keys_i(VALUE key, VALUE value, VALUE ary)
01548 {
01549     rb_ary_push(ary, key);
01550     return ST_CONTINUE;
01551 }
01552 
01553 /*
01554  *  call-seq:
01555  *     hsh.keys    -> array
01556  *
01557  *  Returns a new array populated with the keys from this hash. See also
01558  *  <code>Hash#values</code>.
01559  *
01560  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
01561  *     h.keys   #=> ["a", "b", "c", "d"]
01562  *
01563  */
01564 
01565 static VALUE
01566 rb_hash_keys(VALUE hash)
01567 {
01568     VALUE ary;
01569 
01570     ary = rb_ary_new();
01571     rb_hash_foreach(hash, keys_i, ary);
01572 
01573     return ary;
01574 }
01575 
01576 static int
01577 values_i(VALUE key, VALUE value, VALUE ary)
01578 {
01579     rb_ary_push(ary, value);
01580     return ST_CONTINUE;
01581 }
01582 
01583 /*
01584  *  call-seq:
01585  *     hsh.values    -> array
01586  *
01587  *  Returns a new array populated with the values from <i>hsh</i>. See
01588  *  also <code>Hash#keys</code>.
01589  *
01590  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01591  *     h.values   #=> [100, 200, 300]
01592  *
01593  */
01594 
01595 static VALUE
01596 rb_hash_values(VALUE hash)
01597 {
01598     VALUE ary;
01599 
01600     ary = rb_ary_new();
01601     rb_hash_foreach(hash, values_i, ary);
01602 
01603     return ary;
01604 }
01605 
01606 /*
01607  *  call-seq:
01608  *     hsh.has_key?(key)    -> true or false
01609  *     hsh.include?(key)    -> true or false
01610  *     hsh.key?(key)        -> true or false
01611  *     hsh.member?(key)     -> true or false
01612  *
01613  *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
01614  *
01615  *     h = { "a" => 100, "b" => 200 }
01616  *     h.has_key?("a")   #=> true
01617  *     h.has_key?("z")   #=> false
01618  *
01619  */
01620 
01621 static VALUE
01622 rb_hash_has_key(VALUE hash, VALUE key)
01623 {
01624     if (!RHASH(hash)->ntbl)
01625         return Qfalse;
01626     if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
01627         return Qtrue;
01628     }
01629     return Qfalse;
01630 }
01631 
01632 static int
01633 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
01634 {
01635     VALUE *data = (VALUE *)arg;
01636 
01637     if (rb_equal(value, data[1])) {
01638         data[0] = Qtrue;
01639         return ST_STOP;
01640     }
01641     return ST_CONTINUE;
01642 }
01643 
01644 /*
01645  *  call-seq:
01646  *     hsh.has_value?(value)    -> true or false
01647  *     hsh.value?(value)        -> true or false
01648  *
01649  *  Returns <code>true</code> if the given value is present for some key
01650  *  in <i>hsh</i>.
01651  *
01652  *     h = { "a" => 100, "b" => 200 }
01653  *     h.has_value?(100)   #=> true
01654  *     h.has_value?(999)   #=> false
01655  */
01656 
01657 static VALUE
01658 rb_hash_has_value(VALUE hash, VALUE val)
01659 {
01660     VALUE data[2];
01661 
01662     data[0] = Qfalse;
01663     data[1] = val;
01664     rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
01665     return data[0];
01666 }
01667 
01668 struct equal_data {
01669     VALUE result;
01670     st_table *tbl;
01671     int eql;
01672 };
01673 
01674 static int
01675 eql_i(VALUE key, VALUE val1, VALUE arg)
01676 {
01677     struct equal_data *data = (struct equal_data *)arg;
01678     st_data_t val2;
01679 
01680     if (!st_lookup(data->tbl, key, &val2)) {
01681         data->result = Qfalse;
01682         return ST_STOP;
01683     }
01684     if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
01685         data->result = Qfalse;
01686         return ST_STOP;
01687     }
01688     return ST_CONTINUE;
01689 }
01690 
01691 static VALUE
01692 recursive_eql(VALUE hash, VALUE dt, int recur)
01693 {
01694     struct equal_data *data;
01695 
01696     if (recur) return Qtrue;    /* Subtle! */
01697     data = (struct equal_data*)dt;
01698     data->result = Qtrue;
01699     rb_hash_foreach(hash, eql_i, dt);
01700 
01701     return data->result;
01702 }
01703 
01704 static VALUE
01705 hash_equal(VALUE hash1, VALUE hash2, int eql)
01706 {
01707     struct equal_data data;
01708 
01709     if (hash1 == hash2) return Qtrue;
01710     if (!RB_TYPE_P(hash2, T_HASH)) {
01711         if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
01712             return Qfalse;
01713         }
01714         if (eql)
01715             return rb_eql(hash2, hash1);
01716         else
01717             return rb_equal(hash2, hash1);
01718     }
01719     if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
01720         return Qfalse;
01721     if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
01722         return Qtrue;
01723     if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
01724         return Qfalse;
01725 #if 0
01726     if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
01727           FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
01728         return Qfalse;
01729 #endif
01730 
01731     data.tbl = RHASH(hash2)->ntbl;
01732     data.eql = eql;
01733     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
01734 }
01735 
01736 /*
01737  *  call-seq:
01738  *     hsh == other_hash    -> true or false
01739  *
01740  *  Equality---Two hashes are equal if they each contain the same number
01741  *  of keys and if each key-value pair is equal to (according to
01742  *  <code>Object#==</code>) the corresponding elements in the other
01743  *  hash.
01744  *
01745  *     h1 = { "a" => 1, "c" => 2 }
01746  *     h2 = { 7 => 35, "c" => 2, "a" => 1 }
01747  *     h3 = { "a" => 1, "c" => 2, 7 => 35 }
01748  *     h4 = { "a" => 1, "d" => 2, "f" => 35 }
01749  *     h1 == h2   #=> false
01750  *     h2 == h3   #=> true
01751  *     h3 == h4   #=> false
01752  *
01753  */
01754 
01755 static VALUE
01756 rb_hash_equal(VALUE hash1, VALUE hash2)
01757 {
01758     return hash_equal(hash1, hash2, FALSE);
01759 }
01760 
01761 /*
01762  *  call-seq:
01763  *     hash.eql?(other)  -> true or false
01764  *
01765  *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are
01766  *  both hashes with the same content.
01767  */
01768 
01769 static VALUE
01770 rb_hash_eql(VALUE hash1, VALUE hash2)
01771 {
01772     return hash_equal(hash1, hash2, TRUE);
01773 }
01774 
01775 static int
01776 hash_i(VALUE key, VALUE val, VALUE arg)
01777 {
01778     st_index_t *hval = (st_index_t *)arg;
01779     st_index_t hdata[2];
01780 
01781     hdata[0] = rb_hash(key);
01782     hdata[1] = rb_hash(val);
01783     *hval ^= st_hash(hdata, sizeof(hdata), 0);
01784     return ST_CONTINUE;
01785 }
01786 
01787 static VALUE
01788 recursive_hash(VALUE hash, VALUE dummy, int recur)
01789 {
01790     st_index_t hval;
01791 
01792     if (!RHASH(hash)->ntbl)
01793         return LONG2FIX(0);
01794     hval = RHASH(hash)->ntbl->num_entries;
01795     if (!hval) return LONG2FIX(0);
01796     if (recur)
01797         hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval);
01798     else
01799         rb_hash_foreach(hash, hash_i, (VALUE)&hval);
01800     hval = rb_hash_end(hval);
01801     return INT2FIX(hval);
01802 }
01803 
01804 /*
01805  *  call-seq:
01806  *     hsh.hash   -> fixnum
01807  *
01808  *  Compute a hash-code for this hash. Two hashes with the same content
01809  *  will have the same hash code (and will compare using <code>eql?</code>).
01810  */
01811 
01812 static VALUE
01813 rb_hash_hash(VALUE hash)
01814 {
01815     return rb_exec_recursive_outer(recursive_hash, hash, 0);
01816 }
01817 
01818 static int
01819 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
01820 {
01821     rb_hash_aset(hash, value, key);
01822     return ST_CONTINUE;
01823 }
01824 
01825 /*
01826  *  call-seq:
01827  *     hsh.invert -> new_hash
01828  *
01829  *  Returns a new hash created by using <i>hsh</i>'s values as keys, and
01830  *  the keys as values.
01831  *
01832  *     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
01833  *     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
01834  *
01835  */
01836 
01837 static VALUE
01838 rb_hash_invert(VALUE hash)
01839 {
01840     VALUE h = rb_hash_new();
01841 
01842     rb_hash_foreach(hash, rb_hash_invert_i, h);
01843     return h;
01844 }
01845 
01846 static int
01847 rb_hash_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
01848 {
01849     *value = arg;
01850     return ST_CONTINUE;
01851 }
01852 
01853 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
01854 
01855 static int
01856 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
01857 {
01858     RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
01859     return ST_CONTINUE;
01860 }
01861 
01862 static int
01863 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
01864 {
01865     VALUE newvalue = (VALUE)arg;
01866     if (existing) {
01867         newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
01868     }
01869     *value = (st_data_t)newvalue;
01870     return ST_CONTINUE;
01871 }
01872 
01873 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
01874 
01875 static int
01876 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
01877 {
01878     RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
01879     return ST_CONTINUE;
01880 }
01881 
01882 /*
01883  *  call-seq:
01884  *     hsh.merge!(other_hash)                                 -> hsh
01885  *     hsh.update(other_hash)                                 -> hsh
01886  *     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
01887  *     hsh.update(other_hash){|key, oldval, newval| block}    -> hsh
01888  *
01889  *  Adds the contents of _other_hash_ to _hsh_.  If no block is specified,
01890  *  entries with duplicate keys are overwritten with the values from
01891  *  _other_hash_, otherwise the value of each duplicate key is determined by
01892  *  calling the block with the key, its value in _hsh_ and its value in
01893  *  _other_hash_.
01894  *
01895  *     h1 = { "a" => 100, "b" => 200 }
01896  *     h2 = { "b" => 254, "c" => 300 }
01897  *     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
01898  *
01899  *     h1 = { "a" => 100, "b" => 200 }
01900  *     h2 = { "b" => 254, "c" => 300 }
01901  *     h1.merge!(h2) { |key, v1, v2| v1 }
01902  *                     #=> {"a"=>100, "b"=>200, "c"=>300}
01903  */
01904 
01905 static VALUE
01906 rb_hash_update(VALUE hash1, VALUE hash2)
01907 {
01908     rb_hash_modify(hash1);
01909     hash2 = to_hash(hash2);
01910     if (rb_block_given_p()) {
01911         rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
01912     }
01913     else {
01914         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
01915     }
01916     return hash1;
01917 }
01918 
01919 struct update_arg {
01920     VALUE hash;
01921     VALUE value;
01922     rb_hash_update_func *func;
01923 };
01924 
01925 static int
01926 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, st_data_t arg0, int existing)
01927 {
01928     struct update_arg *arg = (struct update_arg *)arg0;
01929     VALUE newvalue = arg->value;
01930     if (existing) {
01931         newvalue = (*arg->func)((VALUE)*key, (VALUE)*value, newvalue);
01932     }
01933     *value = (st_data_t)newvalue;
01934     return ST_CONTINUE;
01935 }
01936 
01937 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
01938 
01939 static int
01940 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
01941 {
01942     struct update_arg *arg = (struct update_arg *)arg0;
01943     VALUE hash = arg->hash;
01944 
01945     arg->value = value;
01946     RHASH_UPDATE(hash, key, rb_hash_update_func_callback, arg);
01947     return ST_CONTINUE;
01948 }
01949 
01950 VALUE
01951 rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
01952 {
01953     rb_hash_modify(hash1);
01954     hash2 = to_hash(hash2);
01955     if (func) {
01956         struct update_arg arg;
01957         arg.hash = hash1;
01958         arg.func = func;
01959         rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
01960     }
01961     else {
01962         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
01963     }
01964     return hash1;
01965 }
01966 
01967 /*
01968  *  call-seq:
01969  *     hsh.merge(other_hash)                              -> new_hash
01970  *     hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
01971  *
01972  *  Returns a new hash containing the contents of <i>other_hash</i> and
01973  *  the contents of <i>hsh</i>. If no block is specified, the value for
01974  *  entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
01975  *  the value for each duplicate key is determined by calling the block
01976  *  with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
01977  *
01978  *     h1 = { "a" => 100, "b" => 200 }
01979  *     h2 = { "b" => 254, "c" => 300 }
01980  *     h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
01981  *     h1.merge(h2){|key, oldval, newval| newval - oldval}
01982  *                    #=> {"a"=>100, "b"=>54,  "c"=>300}
01983  *     h1             #=> {"a"=>100, "b"=>200}
01984  *
01985  */
01986 
01987 static VALUE
01988 rb_hash_merge(VALUE hash1, VALUE hash2)
01989 {
01990     return rb_hash_update(rb_obj_dup(hash1), hash2);
01991 }
01992 
01993 static int
01994 assoc_i(VALUE key, VALUE val, VALUE arg)
01995 {
01996     VALUE *args = (VALUE *)arg;
01997 
01998     if (RTEST(rb_equal(args[0], key))) {
01999         args[1] = rb_assoc_new(key, val);
02000         return ST_STOP;
02001     }
02002     return ST_CONTINUE;
02003 }
02004 
02005 /*
02006  *  call-seq:
02007  *     hash.assoc(obj)   ->  an_array  or  nil
02008  *
02009  *  Searches through the hash comparing _obj_ with the key using <code>==</code>.
02010  *  Returns the key-value pair (two elements array) or +nil+
02011  *  if no match is found.  See <code>Array#assoc</code>.
02012  *
02013  *     h = {"colors"  => ["red", "blue", "green"],
02014  *          "letters" => ["a", "b", "c" ]}
02015  *     h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
02016  *     h.assoc("foo")      #=> nil
02017  */
02018 
02019 VALUE
02020 rb_hash_assoc(VALUE hash, VALUE obj)
02021 {
02022     VALUE args[2];
02023 
02024     args[0] = obj;
02025     args[1] = Qnil;
02026     rb_hash_foreach(hash, assoc_i, (VALUE)args);
02027     return args[1];
02028 }
02029 
02030 static int
02031 rassoc_i(VALUE key, VALUE val, VALUE arg)
02032 {
02033     VALUE *args = (VALUE *)arg;
02034 
02035     if (RTEST(rb_equal(args[0], val))) {
02036         args[1] = rb_assoc_new(key, val);
02037         return ST_STOP;
02038     }
02039     return ST_CONTINUE;
02040 }
02041 
02042 /*
02043  *  call-seq:
02044  *     hash.rassoc(obj) -> an_array or nil
02045  *
02046  *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
02047  *  Returns the first key-value pair (two-element array) that matches. See
02048  *  also <code>Array#rassoc</code>.
02049  *
02050  *     a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
02051  *     a.rassoc("two")    #=> [2, "two"]
02052  *     a.rassoc("four")   #=> nil
02053  */
02054 
02055 VALUE
02056 rb_hash_rassoc(VALUE hash, VALUE obj)
02057 {
02058     VALUE args[2];
02059 
02060     args[0] = obj;
02061     args[1] = Qnil;
02062     rb_hash_foreach(hash, rassoc_i, (VALUE)args);
02063     return args[1];
02064 }
02065 
02066 /*
02067  *  call-seq:
02068  *     hash.flatten -> an_array
02069  *     hash.flatten(level) -> an_array
02070  *
02071  *  Returns a new array that is a one-dimensional flattening of this
02072  *  hash. That is, for every key or value that is an array, extract
02073  *  its elements into the new array.  Unlike Array#flatten, this
02074  *  method does not flatten recursively by default.  The optional
02075  *  <i>level</i> argument determines the level of recursion to flatten.
02076  *
02077  *     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
02078  *     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
02079  *     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
02080  */
02081 
02082 static VALUE
02083 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
02084 {
02085     VALUE ary, tmp;
02086 
02087     ary = rb_hash_to_a(hash);
02088     if (argc == 0) {
02089         argc = 1;
02090         tmp = INT2FIX(1);
02091         argv = &tmp;
02092     }
02093     rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
02094     return ary;
02095 }
02096 
02097 /*
02098  *  call-seq:
02099  *     hsh.compare_by_identity -> hsh
02100  *
02101  *  Makes <i>hsh</i> compare its keys by their identity, i.e. it
02102  *  will consider exact same objects as same keys.
02103  *
02104  *     h1 = { "a" => 100, "b" => 200, :c => "c" }
02105  *     h1["a"]        #=> 100
02106  *     h1.compare_by_identity
02107  *     h1.compare_by_identity? #=> true
02108  *     h1["a"]        #=> nil  # different objects.
02109  *     h1[:c]         #=> "c"  # same symbols are all same.
02110  *
02111  */
02112 
02113 static VALUE
02114 rb_hash_compare_by_id(VALUE hash)
02115 {
02116     rb_hash_modify(hash);
02117     RHASH(hash)->ntbl->type = &identhash;
02118     rb_hash_rehash(hash);
02119     return hash;
02120 }
02121 
02122 /*
02123  *  call-seq:
02124  *     hsh.compare_by_identity? -> true or false
02125  *
02126  *  Returns <code>true</code> if <i>hsh</i> will compare its keys by
02127  *  their identity.  Also see <code>Hash#compare_by_identity</code>.
02128  *
02129  */
02130 
02131 static VALUE
02132 rb_hash_compare_by_id_p(VALUE hash)
02133 {
02134     if (!RHASH(hash)->ntbl)
02135         return Qfalse;
02136     if (RHASH(hash)->ntbl->type == &identhash) {
02137         return Qtrue;
02138     }
02139     return Qfalse;
02140 }
02141 
02142 static int path_tainted = -1;
02143 
02144 static char **origenviron;
02145 #ifdef _WIN32
02146 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
02147 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
02148 static char **my_environ;
02149 #undef environ
02150 #define environ my_environ
02151 #undef getenv
02152 #define getenv(n) rb_w32_ugetenv(n)
02153 #elif defined(__APPLE__)
02154 #undef environ
02155 #define environ (*_NSGetEnviron())
02156 #define GET_ENVIRON(e) (e)
02157 #define FREE_ENVIRON(e)
02158 #else
02159 extern char **environ;
02160 #define GET_ENVIRON(e) (e)
02161 #define FREE_ENVIRON(e)
02162 #endif
02163 #ifdef ENV_IGNORECASE
02164 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
02165 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
02166 #else
02167 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
02168 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
02169 #endif
02170 
02171 static VALUE
02172 env_str_new(const char *ptr, long len)
02173 {
02174 #ifdef _WIN32
02175     VALUE str = rb_str_conv_enc(rb_str_new(ptr, len), rb_utf8_encoding(), rb_locale_encoding());
02176 #else
02177     VALUE str = rb_locale_str_new(ptr, len);
02178 #endif
02179 
02180     rb_obj_freeze(str);
02181     return str;
02182 }
02183 
02184 static VALUE
02185 env_str_new2(const char *ptr)
02186 {
02187     if (!ptr) return Qnil;
02188     return env_str_new(ptr, strlen(ptr));
02189 }
02190 
02191 static VALUE
02192 env_delete(VALUE obj, VALUE name)
02193 {
02194     char *nam, *val;
02195 
02196     rb_secure(4);
02197     SafeStringValue(name);
02198     nam = RSTRING_PTR(name);
02199     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02200         rb_raise(rb_eArgError, "bad environment variable name");
02201     }
02202     val = getenv(nam);
02203     if (val) {
02204         VALUE value = env_str_new2(val);
02205 
02206         ruby_setenv(nam, 0);
02207         if (ENVMATCH(nam, PATH_ENV)) {
02208             path_tainted = 0;
02209         }
02210         return value;
02211     }
02212     return Qnil;
02213 }
02214 
02215 /*
02216  * call-seq:
02217  *   ENV.delete(name)            -> value
02218  *   ENV.delete(name) { |name| } -> value
02219  *
02220  * Deletes the environment variable with +name+ and returns the value of the
02221  * variable.  If a block is given it will be called when the named environment
02222  * does not exist.
02223  */
02224 static VALUE
02225 env_delete_m(VALUE obj, VALUE name)
02226 {
02227     VALUE val;
02228 
02229     val = env_delete(obj, name);
02230     if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
02231     return val;
02232 }
02233 
02234 static int env_path_tainted(const char *);
02235 
02236 /*
02237  * call-seq:
02238  *   ENV[name] -> value
02239  *
02240  * Retrieves the +value+ for environment variable +name+ as a String.  Returns
02241  * +nil+ if the named variable does not exist.
02242  */
02243 static VALUE
02244 rb_f_getenv(VALUE obj, VALUE name)
02245 {
02246     char *nam, *env;
02247 
02248     rb_secure(4);
02249     SafeStringValue(name);
02250     nam = RSTRING_PTR(name);
02251     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02252         rb_raise(rb_eArgError, "bad environment variable name");
02253     }
02254     env = getenv(nam);
02255     if (env) {
02256         if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) {
02257 #ifdef _WIN32
02258             VALUE str = rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02259 #else
02260             VALUE str = rb_filesystem_str_new_cstr(env);
02261 #endif
02262 
02263             rb_obj_freeze(str);
02264             return str;
02265         }
02266         return env_str_new2(env);
02267     }
02268     return Qnil;
02269 }
02270 
02271 /*
02272  * :yield: missing_name
02273  * call-seq:
02274  *   ENV.fetch(name)                        -> value
02275  *   ENV.fetch(name, default)               -> value
02276  *   ENV.fetch(name) { |missing_name| ... } -> value
02277  *
02278  * Retrieves the environment variable +name+.
02279  *
02280  * If the given name does not exist and neither +default+ nor a block a
02281  * provided an IndexError is raised.  If a block is given it is called with
02282  * the missing name to provide a value.  If a default value is given it will
02283  * be returned when no block is given.
02284  */
02285 static VALUE
02286 env_fetch(int argc, VALUE *argv)
02287 {
02288     VALUE key, if_none;
02289     long block_given;
02290     char *nam, *env;
02291 
02292     rb_secure(4);
02293     rb_scan_args(argc, argv, "11", &key, &if_none);
02294     block_given = rb_block_given_p();
02295     if (block_given && argc == 2) {
02296         rb_warn("block supersedes default value argument");
02297     }
02298     SafeStringValue(key);
02299     nam = RSTRING_PTR(key);
02300     if (memchr(nam, '\0', RSTRING_LEN(key))) {
02301         rb_raise(rb_eArgError, "bad environment variable name");
02302     }
02303     env = getenv(nam);
02304     if (!env) {
02305         if (block_given) return rb_yield(key);
02306         if (argc == 1) {
02307             rb_raise(rb_eKeyError, "key not found");
02308         }
02309         return if_none;
02310     }
02311     if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env))
02312 #ifdef _WIN32
02313         return rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02314 #else
02315         return rb_filesystem_str_new_cstr(env);
02316 #endif
02317     return env_str_new2(env);
02318 }
02319 
02320 static void
02321 path_tainted_p(const char *path)
02322 {
02323     path_tainted = rb_path_check(path)?0:1;
02324 }
02325 
02326 static int
02327 env_path_tainted(const char *path)
02328 {
02329     if (path_tainted < 0) {
02330         path_tainted_p(path);
02331     }
02332     return path_tainted;
02333 }
02334 
02335 int
02336 rb_env_path_tainted(void)
02337 {
02338     if (path_tainted < 0) {
02339         path_tainted_p(getenv(PATH_ENV));
02340     }
02341     return path_tainted;
02342 }
02343 
02344 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
02345 #elif defined __sun
02346 static int
02347 in_origenv(const char *str)
02348 {
02349     char **env;
02350     for (env = origenviron; *env; ++env) {
02351         if (*env == str) return 1;
02352     }
02353     return 0;
02354 }
02355 #else
02356 static int
02357 envix(const char *nam)
02358 {
02359     register int i, len = strlen(nam);
02360     char **env;
02361 
02362     env = GET_ENVIRON(environ);
02363     for (i = 0; env[i]; i++) {
02364         if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
02365             break;                      /* memcmp must come first to avoid */
02366     }                                   /* potential SEGV's */
02367     FREE_ENVIRON(environ);
02368     return i;
02369 }
02370 #endif
02371 
02372 #if defined(_WIN32)
02373 static size_t
02374 getenvsize(const char* p)
02375 {
02376     const char* porg = p;
02377     while (*p++) p += strlen(p) + 1;
02378     return p - porg + 1;
02379 }
02380 static size_t
02381 getenvblocksize()
02382 {
02383     return (rb_w32_osver() >= 5) ? 32767 : 5120;
02384 }
02385 #endif
02386 
02387 void
02388 ruby_setenv(const char *name, const char *value)
02389 {
02390 #if defined(_WIN32)
02391     VALUE buf;
02392     int failed = 0;
02393     if (strchr(name, '=')) {
02394       fail:
02395         errno = EINVAL;
02396         rb_sys_fail("ruby_setenv");
02397     }
02398     if (value) {
02399         const char* p = GetEnvironmentStringsA();
02400         if (!p) goto fail; /* never happen */
02401         if (strlen(name) + 2 + strlen(value) + getenvsize(p) >= getenvblocksize()) {
02402             goto fail;  /* 2 for '=' & '\0' */
02403         }
02404         buf = rb_sprintf("%s=%s", name, value);
02405     }
02406     else {
02407         buf = rb_sprintf("%s=", name);
02408     }
02409     failed = putenv(RSTRING_PTR(buf));
02410     /* even if putenv() failed, clean up and try to delete the
02411      * variable from the system area. */
02412     rb_str_resize(buf, 0);
02413     if (!value || !*value) {
02414         /* putenv() doesn't handle empty value */
02415         if (!SetEnvironmentVariable(name, value) &&
02416             GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
02417     }
02418     if (failed) goto fail;
02419 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
02420 #undef setenv
02421 #undef unsetenv
02422     if (value) {
02423         if (setenv(name, value, 1))
02424             rb_sys_fail("setenv");
02425     } else {
02426 #ifdef VOID_UNSETENV
02427         unsetenv(name);
02428 #else
02429         if (unsetenv(name))
02430             rb_sys_fail("unsetenv");
02431 #endif
02432     }
02433 #elif defined __sun
02434     size_t len;
02435     char **env_ptr, *str;
02436     if (strchr(name, '=')) {
02437         errno = EINVAL;
02438         rb_sys_fail("ruby_setenv");
02439     }
02440     len = strlen(name);
02441     for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
02442         if (!strncmp(str, name, len) && str[len] == '=') {
02443             if (!in_origenv(str)) free(str);
02444             while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
02445             break;
02446         }
02447     }
02448     if (value) {
02449         str = malloc(len += strlen(value) + 2);
02450         snprintf(str, len, "%s=%s", name, value);
02451         if (putenv(str))
02452             rb_sys_fail("putenv");
02453     }
02454 #else  /* WIN32 */
02455     size_t len;
02456     int i;
02457     if (strchr(name, '=')) {
02458         errno = EINVAL;
02459         rb_sys_fail("ruby_setenv");
02460     }
02461     i=envix(name);                      /* where does it go? */
02462 
02463     if (environ == origenviron) {       /* need we copy environment? */
02464         int j;
02465         int max;
02466         char **tmpenv;
02467 
02468         for (max = i; environ[max]; max++) ;
02469         tmpenv = ALLOC_N(char*, max+2);
02470         for (j=0; j<max; j++)           /* copy environment */
02471             tmpenv[j] = ruby_strdup(environ[j]);
02472         tmpenv[max] = 0;
02473         environ = tmpenv;               /* tell exec where it is now */
02474     }
02475     if (environ[i]) {
02476         char **envp = origenviron;
02477         while (*envp && *envp != environ[i]) envp++;
02478         if (!*envp)
02479             xfree(environ[i]);
02480         if (!value) {
02481             while (environ[i]) {
02482                 environ[i] = environ[i+1];
02483                 i++;
02484             }
02485             return;
02486         }
02487     }
02488     else {                      /* does not exist yet */
02489         if (!value) return;
02490         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
02491         environ[i+1] = 0;       /* make sure it's null terminated */
02492     }
02493     len = strlen(name) + strlen(value) + 2;
02494     environ[i] = ALLOC_N(char, len);
02495     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
02496 #endif /* WIN32 */
02497 }
02498 
02499 void
02500 ruby_unsetenv(const char *name)
02501 {
02502     ruby_setenv(name, 0);
02503 }
02504 
02505 /*
02506  * call-seq:
02507  *   ENV[name] = value
02508  *   ENV.store(name, value) -> value
02509  *
02510  * Sets the environment variable +name+ to +value+.  If the value given is
02511  * +nil+ the environment variable is deleted.
02512  *
02513  */
02514 static VALUE
02515 env_aset(VALUE obj, VALUE nm, VALUE val)
02516 {
02517     char *name, *value;
02518 
02519     if (rb_safe_level() >= 4) {
02520         rb_raise(rb_eSecurityError, "can't change environment variable");
02521     }
02522 
02523     if (NIL_P(val)) {
02524         env_delete(obj, nm);
02525         return Qnil;
02526     }
02527     StringValue(nm);
02528     StringValue(val);
02529     name = RSTRING_PTR(nm);
02530     value = RSTRING_PTR(val);
02531     if (memchr(name, '\0', RSTRING_LEN(nm)))
02532         rb_raise(rb_eArgError, "bad environment variable name");
02533     if (memchr(value, '\0', RSTRING_LEN(val)))
02534         rb_raise(rb_eArgError, "bad environment variable value");
02535 
02536     ruby_setenv(name, value);
02537     if (ENVMATCH(name, PATH_ENV)) {
02538         if (OBJ_TAINTED(val)) {
02539             /* already tainted, no check */
02540             path_tainted = 1;
02541             return val;
02542         }
02543         else {
02544             path_tainted_p(value);
02545         }
02546     }
02547     return val;
02548 }
02549 
02550 /*
02551  * call-seq:
02552  *   ENV.keys -> Array
02553  *
02554  * Returns every environment variable name in an Array
02555  */
02556 static VALUE
02557 env_keys(void)
02558 {
02559     char **env;
02560     VALUE ary;
02561 
02562     rb_secure(4);
02563     ary = rb_ary_new();
02564     env = GET_ENVIRON(environ);
02565     while (*env) {
02566         char *s = strchr(*env, '=');
02567         if (s) {
02568             rb_ary_push(ary, env_str_new(*env, s-*env));
02569         }
02570         env++;
02571     }
02572     FREE_ENVIRON(environ);
02573     return ary;
02574 }
02575 
02576 static VALUE
02577 rb_env_size(VALUE ehash)
02578 {
02579     char **env;
02580     long cnt = 0;
02581 
02582     rb_secure(4);
02583 
02584     env = GET_ENVIRON(environ);
02585     for (; *env ; ++env) {
02586         if (strchr(*env, '=')) {
02587             cnt++;
02588         }
02589     }
02590     FREE_ENVIRON(environ);
02591     return LONG2FIX(cnt);
02592 }
02593 
02594 /*
02595  * call-seq:
02596  *   ENV.each_key { |name| } -> Hash
02597  *   ENV.each_key            -> Enumerator
02598  *
02599  * Yields each environment variable name.
02600  *
02601  * An Enumerator is returned if no block is given.
02602  */
02603 static VALUE
02604 env_each_key(VALUE ehash)
02605 {
02606     VALUE keys;
02607     long i;
02608 
02609     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02610     keys = env_keys();  /* rb_secure(4); */
02611     for (i=0; i<RARRAY_LEN(keys); i++) {
02612         rb_yield(RARRAY_PTR(keys)[i]);
02613     }
02614     return ehash;
02615 }
02616 
02617 /*
02618  * call-seq:
02619  *   ENV.values -> Array
02620  *
02621  * Returns every environment variable value as an Array
02622  */
02623 static VALUE
02624 env_values(void)
02625 {
02626     VALUE ary;
02627     char **env;
02628 
02629     rb_secure(4);
02630     ary = rb_ary_new();
02631     env = GET_ENVIRON(environ);
02632     while (*env) {
02633         char *s = strchr(*env, '=');
02634         if (s) {
02635             rb_ary_push(ary, env_str_new2(s+1));
02636         }
02637         env++;
02638     }
02639     FREE_ENVIRON(environ);
02640     return ary;
02641 }
02642 
02643 /*
02644  * call-seq:
02645  *   ENV.each_value { |value| } -> Hash
02646  *   ENV.each_value             -> Enumerator
02647  *
02648  * Yields each environment variable +value+.
02649  *
02650  * An Enumerator is returned if no block was given.
02651  */
02652 static VALUE
02653 env_each_value(VALUE ehash)
02654 {
02655     VALUE values;
02656     long i;
02657 
02658     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02659     values = env_values();      /* rb_secure(4); */
02660     for (i=0; i<RARRAY_LEN(values); i++) {
02661         rb_yield(RARRAY_PTR(values)[i]);
02662     }
02663     return ehash;
02664 }
02665 
02666 /*
02667  * call-seq:
02668  *   ENV.each      { |name, value| } -> Hash
02669  *   ENV.each                        -> Enumerator
02670  *   ENV.each_pair { |name, value| } -> Hash
02671  *   ENV.each_pair                   -> Enumerator
02672  *
02673  * Yields each environment variable +name+ and +value+.
02674  *
02675  * If no block is given an Enumerator is returned.
02676  */
02677 static VALUE
02678 env_each_pair(VALUE ehash)
02679 {
02680     char **env;
02681     VALUE ary;
02682     long i;
02683 
02684     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02685 
02686     rb_secure(4);
02687     ary = rb_ary_new();
02688     env = GET_ENVIRON(environ);
02689     while (*env) {
02690         char *s = strchr(*env, '=');
02691         if (s) {
02692             rb_ary_push(ary, env_str_new(*env, s-*env));
02693             rb_ary_push(ary, env_str_new2(s+1));
02694         }
02695         env++;
02696     }
02697     FREE_ENVIRON(environ);
02698 
02699     for (i=0; i<RARRAY_LEN(ary); i+=2) {
02700         rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]));
02701     }
02702     return ehash;
02703 }
02704 
02705 /*
02706  * call-seq:
02707  *   ENV.reject! { |name, value| } -> ENV or nil
02708  *   ENV.reject!                   -> Enumerator
02709  *
02710  * Equivalent to ENV#delete_if but returns +nil+ if no changes were made.
02711  *
02712  * Returns an Enumerator if no block was given.
02713  */
02714 static VALUE
02715 env_reject_bang(VALUE ehash)
02716 {
02717     volatile VALUE keys;
02718     long i;
02719     int del = 0;
02720 
02721     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02722     keys = env_keys();  /* rb_secure(4); */
02723     RBASIC(keys)->klass = 0;
02724     for (i=0; i<RARRAY_LEN(keys); i++) {
02725         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02726         if (!NIL_P(val)) {
02727             if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02728                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02729                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02730                 del++;
02731             }
02732         }
02733     }
02734     if (del == 0) return Qnil;
02735     return envtbl;
02736 }
02737 
02738 /*
02739  * call-seq:
02740  *   ENV.delete_if { |name, value| } -> Hash
02741  *   ENV.delete_if                   -> Enumerator
02742  *
02743  * Deletes every environment variable for which the block evaluates to +true+.
02744  *
02745  * If no block is given an enumerator is returned instead.
02746  */
02747 static VALUE
02748 env_delete_if(VALUE ehash)
02749 {
02750     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02751     env_reject_bang(ehash);
02752     return envtbl;
02753 }
02754 
02755 /*
02756  * call-seq:
02757  *   ENV.values_at(name, ...) -> Array
02758  *
02759  * Returns an array containing the environment variable values associated with
02760  * the given names.  See also ENV.select.
02761  */
02762 static VALUE
02763 env_values_at(int argc, VALUE *argv)
02764 {
02765     VALUE result;
02766     long i;
02767 
02768     rb_secure(4);
02769     result = rb_ary_new();
02770     for (i=0; i<argc; i++) {
02771         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
02772     }
02773     return result;
02774 }
02775 
02776 /*
02777  * call-seq:
02778  *   ENV.select { |name, value| } -> Hash
02779  *   ENV.select                   -> Enumerator
02780  *
02781  * Returns a copy of the environment for entries where the block returns true.
02782  *
02783  * Returns an Enumerator if no block was given.
02784  */
02785 static VALUE
02786 env_select(VALUE ehash)
02787 {
02788     VALUE result;
02789     char **env;
02790 
02791     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02792     rb_secure(4);
02793     result = rb_hash_new();
02794     env = GET_ENVIRON(environ);
02795     while (*env) {
02796         char *s = strchr(*env, '=');
02797         if (s) {
02798             VALUE k = env_str_new(*env, s-*env);
02799             VALUE v = env_str_new2(s+1);
02800             if (RTEST(rb_yield_values(2, k, v))) {
02801                 rb_hash_aset(result, k, v);
02802             }
02803         }
02804         env++;
02805     }
02806     FREE_ENVIRON(environ);
02807 
02808     return result;
02809 }
02810 
02811 /*
02812  * call-seq:
02813  *   ENV.select! { |name, value| } -> ENV or nil
02814  *   ENV.select!                   -> Enumerator
02815  *
02816  * Equivalent to ENV#keep_if but returns +nil+ if no changes were made.
02817  */
02818 static VALUE
02819 env_select_bang(VALUE ehash)
02820 {
02821     volatile VALUE keys;
02822     long i;
02823     int del = 0;
02824 
02825     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02826     keys = env_keys();  /* rb_secure(4); */
02827     RBASIC(keys)->klass = 0;
02828     for (i=0; i<RARRAY_LEN(keys); i++) {
02829         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02830         if (!NIL_P(val)) {
02831             if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02832                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02833                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02834                 del++;
02835             }
02836         }
02837     }
02838     if (del == 0) return Qnil;
02839     return envtbl;
02840 }
02841 
02842 /*
02843  * call-seq:
02844  *   ENV.keep_if { |name, value| } -> Hash
02845  *   ENV.keep_if                   -> Enumerator
02846  *
02847  * Deletes every environment variable where the block evaluates to +false+.
02848  *
02849  * Returns an enumerator if no block was given.
02850  */
02851 static VALUE
02852 env_keep_if(VALUE ehash)
02853 {
02854     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02855     env_select_bang(ehash);
02856     return envtbl;
02857 }
02858 
02859 /*
02860  * call-seq:
02861  *   ENV.clear
02862  *
02863  * Removes every environment variable.
02864  */
02865 VALUE
02866 rb_env_clear(void)
02867 {
02868     volatile VALUE keys;
02869     long i;
02870 
02871     keys = env_keys();  /* rb_secure(4); */
02872     for (i=0; i<RARRAY_LEN(keys); i++) {
02873         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02874         if (!NIL_P(val)) {
02875             env_delete(Qnil, RARRAY_PTR(keys)[i]);
02876         }
02877     }
02878     return envtbl;
02879 }
02880 
02881 /*
02882  * call-seq:
02883  *   ENV.to_s -> "ENV"
02884  *
02885  * Returns "ENV"
02886  */
02887 static VALUE
02888 env_to_s(void)
02889 {
02890     return rb_usascii_str_new2("ENV");
02891 }
02892 
02893 /*
02894  * call-seq:
02895  *   ENV.inspect -> string
02896  *
02897  * Returns the contents of the environment as a String.
02898  */
02899 static VALUE
02900 env_inspect(void)
02901 {
02902     char **env;
02903     VALUE str, i;
02904 
02905     rb_secure(4);
02906     str = rb_str_buf_new2("{");
02907     env = GET_ENVIRON(environ);
02908     while (*env) {
02909         char *s = strchr(*env, '=');
02910 
02911         if (env != environ) {
02912             rb_str_buf_cat2(str, ", ");
02913         }
02914         if (s) {
02915             rb_str_buf_cat2(str, "\"");
02916             rb_str_buf_cat(str, *env, s-*env);
02917             rb_str_buf_cat2(str, "\"=>");
02918             i = rb_inspect(rb_str_new2(s+1));
02919             rb_str_buf_append(str, i);
02920         }
02921         env++;
02922     }
02923     FREE_ENVIRON(environ);
02924     rb_str_buf_cat2(str, "}");
02925     OBJ_TAINT(str);
02926 
02927     return str;
02928 }
02929 
02930 /*
02931  * call-seq:
02932  *   ENV.to_a -> Array
02933  *
02934  * Converts the environment variables into an array of names and value arrays.
02935  *
02936  *   ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
02937  *
02938  */
02939 static VALUE
02940 env_to_a(void)
02941 {
02942     char **env;
02943     VALUE ary;
02944 
02945     rb_secure(4);
02946     ary = rb_ary_new();
02947     env = GET_ENVIRON(environ);
02948     while (*env) {
02949         char *s = strchr(*env, '=');
02950         if (s) {
02951             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
02952                                           env_str_new2(s+1)));
02953         }
02954         env++;
02955     }
02956     FREE_ENVIRON(environ);
02957     return ary;
02958 }
02959 
02960 /*
02961  * call-seq:
02962  *   ENV.rehash
02963  *
02964  * Re-hashing the environment variables does nothing.  It is provided for
02965  * compatibility with Hash.
02966  */
02967 static VALUE
02968 env_none(void)
02969 {
02970     return Qnil;
02971 }
02972 
02973 /*
02974  * call-seq:
02975  *   ENV.length
02976  *   ENV.size
02977  *
02978  * Returns the number of environment variables.
02979  */
02980 static VALUE
02981 env_size(void)
02982 {
02983     int i;
02984     char **env;
02985 
02986     rb_secure(4);
02987     env = GET_ENVIRON(environ);
02988     for (i=0; env[i]; i++)
02989         ;
02990     FREE_ENVIRON(environ);
02991     return INT2FIX(i);
02992 }
02993 
02994 /*
02995  * call-seq:
02996  *   ENV.empty? -> true or false
02997  *
02998  * Returns true when there are no environment variables
02999  */
03000 static VALUE
03001 env_empty_p(void)
03002 {
03003     char **env;
03004 
03005     rb_secure(4);
03006     env = GET_ENVIRON(environ);
03007     if (env[0] == 0) {
03008         FREE_ENVIRON(environ);
03009         return Qtrue;
03010     }
03011     FREE_ENVIRON(environ);
03012     return Qfalse;
03013 }
03014 
03015 /*
03016  * call-seq:
03017  *   ENV.key?(name)     -> true or false
03018  *   ENV.include?(name) -> true or false
03019  *   ENV.has_key?(name) -> true or false
03020  *   ENV.member?(name)  -> true or false
03021  *
03022  * Returns +true+ if there is an environment variable with the given +name+.
03023  */
03024 static VALUE
03025 env_has_key(VALUE env, VALUE key)
03026 {
03027     char *s;
03028 
03029     rb_secure(4);
03030     s = StringValuePtr(key);
03031     if (memchr(s, '\0', RSTRING_LEN(key)))
03032         rb_raise(rb_eArgError, "bad environment variable name");
03033     if (getenv(s)) return Qtrue;
03034     return Qfalse;
03035 }
03036 
03037 /*
03038  * call-seq:
03039  *   ENV.assoc(name) -> Array or nil
03040  *
03041  * Returns an Array of the name and value of the environment variable with
03042  * +name+ or +nil+ if the name cannot be found.
03043  */
03044 static VALUE
03045 env_assoc(VALUE env, VALUE key)
03046 {
03047     char *s, *e;
03048 
03049     rb_secure(4);
03050     s = StringValuePtr(key);
03051     if (memchr(s, '\0', RSTRING_LEN(key)))
03052         rb_raise(rb_eArgError, "bad environment variable name");
03053     e = getenv(s);
03054     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
03055     return Qnil;
03056 }
03057 
03058 /*
03059  * call-seq:
03060  *   ENV.value?(value) -> true or false
03061  *   ENV.has_value?(value) -> true or false
03062  *
03063  * Returns +true+ if there is an environment variable with the given +value+.
03064  */
03065 static VALUE
03066 env_has_value(VALUE dmy, VALUE obj)
03067 {
03068     char **env;
03069 
03070     rb_secure(4);
03071     obj = rb_check_string_type(obj);
03072     if (NIL_P(obj)) return Qnil;
03073     env = GET_ENVIRON(environ);
03074     while (*env) {
03075         char *s = strchr(*env, '=');
03076         if (s++) {
03077             long len = strlen(s);
03078             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03079                 FREE_ENVIRON(environ);
03080                 return Qtrue;
03081             }
03082         }
03083         env++;
03084     }
03085     FREE_ENVIRON(environ);
03086     return Qfalse;
03087 }
03088 
03089 /*
03090  * call-seq:
03091  *   ENV.rassoc(value)
03092  *
03093  * Returns an Array of the name and value of the environment variable with
03094  * +value+ or +nil+ if the value cannot be found.
03095  */
03096 static VALUE
03097 env_rassoc(VALUE dmy, VALUE obj)
03098 {
03099     char **env;
03100 
03101     rb_secure(4);
03102     obj = rb_check_string_type(obj);
03103     if (NIL_P(obj)) return Qnil;
03104     env = GET_ENVIRON(environ);
03105     while (*env) {
03106         char *s = strchr(*env, '=');
03107         if (s++) {
03108             long len = strlen(s);
03109             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03110                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
03111                 FREE_ENVIRON(environ);
03112                 return result;
03113             }
03114         }
03115         env++;
03116     }
03117     FREE_ENVIRON(environ);
03118     return Qnil;
03119 }
03120 
03121 /*
03122  * call-seq:
03123  *   ENV.key(value) -> name
03124  *
03125  * Returns the name of the environment variable with +value+.  If the value is
03126  * not found +nil+ is returned.
03127  */
03128 static VALUE
03129 env_key(VALUE dmy, VALUE value)
03130 {
03131     char **env;
03132     VALUE str;
03133 
03134     rb_secure(4);
03135     StringValue(value);
03136     env = GET_ENVIRON(environ);
03137     while (*env) {
03138         char *s = strchr(*env, '=');
03139         if (s++) {
03140             long len = strlen(s);
03141             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
03142                 str = env_str_new(*env, s-*env-1);
03143                 FREE_ENVIRON(environ);
03144                 return str;
03145             }
03146         }
03147         env++;
03148     }
03149     FREE_ENVIRON(environ);
03150     return Qnil;
03151 }
03152 
03153 /*
03154  * call-seq:
03155  *   ENV.index(value) -> key
03156  *
03157  * Deprecated method that is equivalent to ENV.key
03158  */
03159 static VALUE
03160 env_index(VALUE dmy, VALUE value)
03161 {
03162     rb_warn("ENV.index is deprecated; use ENV.key");
03163     return env_key(dmy, value);
03164 }
03165 
03166 /*
03167  * call-seq:
03168  *   ENV.to_hash -> hash
03169  *   ENV.to_h    -> hash
03170  *
03171  * Creates a hash with a copy of the environment variables.
03172  *
03173  */
03174 static VALUE
03175 env_to_hash(void)
03176 {
03177     char **env;
03178     VALUE hash;
03179 
03180     rb_secure(4);
03181     hash = rb_hash_new();
03182     env = GET_ENVIRON(environ);
03183     while (*env) {
03184         char *s = strchr(*env, '=');
03185         if (s) {
03186             rb_hash_aset(hash, env_str_new(*env, s-*env),
03187                                env_str_new2(s+1));
03188         }
03189         env++;
03190     }
03191     FREE_ENVIRON(environ);
03192     return hash;
03193 }
03194 
03195 /*
03196  * call-seq:
03197  *   ENV.reject { |name, value| } -> Hash
03198  *   ENV.reject                   -> Enumerator
03199  *
03200  * Same as ENV#delete_if, but works on (and returns) a copy of the
03201  * environment.
03202  */
03203 static VALUE
03204 env_reject(void)
03205 {
03206     return rb_hash_delete_if(env_to_hash());
03207 }
03208 
03209 /*
03210  * call-seq:
03211  *   ENV.shift -> Array or nil
03212  *
03213  * Removes an environment variable name-value pair from ENV and returns it as
03214  * an Array.  Returns +nil+ if when the environment is empty.
03215  */
03216 static VALUE
03217 env_shift(void)
03218 {
03219     char **env;
03220 
03221     rb_secure(4);
03222     env = GET_ENVIRON(environ);
03223     if (*env) {
03224         char *s = strchr(*env, '=');
03225         if (s) {
03226             VALUE key = env_str_new(*env, s-*env);
03227             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
03228             env_delete(Qnil, key);
03229             return rb_assoc_new(key, val);
03230         }
03231     }
03232     FREE_ENVIRON(environ);
03233     return Qnil;
03234 }
03235 
03236 /*
03237  * call-seq:
03238  *   ENV.invert -> Hash
03239  *
03240  * Returns a new hash created by using environment variable names as values
03241  * and values as names.
03242  */
03243 static VALUE
03244 env_invert(void)
03245 {
03246     return rb_hash_invert(env_to_hash());
03247 }
03248 
03249 static int
03250 env_replace_i(VALUE key, VALUE val, VALUE keys)
03251 {
03252     env_aset(Qnil, key, val);
03253     if (rb_ary_includes(keys, key)) {
03254         rb_ary_delete(keys, key);
03255     }
03256     return ST_CONTINUE;
03257 }
03258 
03259 /*
03260  * call-seq:
03261  *   ENV.replace(hash) -> env
03262  *
03263  * Replaces the contents of the environment variables with the contents of
03264  * +hash+.
03265  */
03266 static VALUE
03267 env_replace(VALUE env, VALUE hash)
03268 {
03269     volatile VALUE keys;
03270     long i;
03271 
03272     keys = env_keys();  /* rb_secure(4); */
03273     if (env == hash) return env;
03274     hash = to_hash(hash);
03275     rb_hash_foreach(hash, env_replace_i, keys);
03276 
03277     for (i=0; i<RARRAY_LEN(keys); i++) {
03278         env_delete(env, RARRAY_PTR(keys)[i]);
03279     }
03280     return env;
03281 }
03282 
03283 static int
03284 env_update_i(VALUE key, VALUE val)
03285 {
03286     if (rb_block_given_p()) {
03287         val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
03288     }
03289     env_aset(Qnil, key, val);
03290     return ST_CONTINUE;
03291 }
03292 
03293 /*
03294  * call-seq:
03295  *   ENV.update(hash)                                  -> Hash
03296  *   ENV.update(hash) { |name, old_value, new_value| } -> Hash
03297  *
03298  * Adds the contents of +hash+ to the environment variables.  If no block is
03299  * specified entries with duplicate keys are overwritten, otherwise the value
03300  * of each duplicate name is determined by calling the block with the key, its
03301  * value from the environment and its value from the hash.
03302  */
03303 static VALUE
03304 env_update(VALUE env, VALUE hash)
03305 {
03306     rb_secure(4);
03307     if (env == hash) return env;
03308     hash = to_hash(hash);
03309     rb_hash_foreach(hash, env_update_i, 0);
03310     return env;
03311 }
03312 
03313 /*
03314  *  A Hash is a dictionary-like collection of unique keys and their values.
03315  *  Also called associative arrays, they are similar to Arrays, but where an
03316  *  Array uses integers as its index, a Hash allows you to use any object
03317  *  type.
03318  *
03319  *  Hashes enumerate their values in the order that the corresponding keys
03320  *  were inserted.
03321  *
03322  *  A Hash can be easily created by using its implicit form:
03323  *
03324  *    grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
03325  *
03326  *  Hashes allow an alternate syntax form when your keys are always symbols.
03327  *  Instead of
03328  *
03329  *    options = { :font_size => 10, :font_family => "Arial" }
03330  *
03331  *  You could write it as:
03332  *
03333  *    options = { font_size: 10, font_family: "Arial" }
03334  *
03335  *  Each named key is a symbol you can access in hash:
03336  *
03337  *    options[:font_size]  # => 10
03338  *
03339  *  A Hash can also be created through its ::new method:
03340  *
03341  *    grades = Hash.new
03342  *    grades["Dorothy Doe"] = 9
03343  *
03344  *  Hashes have a <em>default value</em> that is returned when accessing
03345  *  keys that do not exist in the hash. If no default is set +nil+ is used.
03346  *  You can set the default value by sending it as an argument to Hash.new:
03347  *
03348  *    grades = Hash.new(0)
03349  *
03350  *  Or by using the #default= method:
03351  *
03352  *    grades = {"Timmy Doe" => 8}
03353  *    grades.default = 0
03354  *
03355  *  Accessing a value in a Hash requires using its key:
03356  *
03357  *    puts grades["Jane Doe"] # => 10
03358  *
03359  *  === Common Uses
03360  *
03361  *  Hashes are an easy way to represent data structures, such as
03362  *
03363  *    books         = {}
03364  *    books[:matz]  = "The Ruby Language"
03365  *    books[:black] = "The Well-Grounded Rubyist"
03366  *
03367  *  Hashes are also commonly used as a way to have named parameters in
03368  *  functions. Note that no brackets are used below. If a hash is the last
03369  *  argument on a method call, no braces are needed, thus creating a really
03370  *  clean interface:
03371  *
03372  *    Person.create(name: "John Doe", age: 27)
03373  *
03374  *    def self.create(params)
03375  *      @name = params[:name]
03376  *      @age  = params[:age]
03377  *    end
03378  *
03379  *  === Hash Keys
03380  *
03381  *  Two objects refer to the same hash key when their <code>hash</code> value
03382  *  is identical and the two objects are <code>eql?</code> to each other.
03383  *
03384  *  A user-defined class may be used as a hash key if the <code>hash</code>
03385  *  and <code>eql?</code> methods are overridden to provide meaningful
03386  *  behavior.  By default, separate instances refer to separate hash keys.
03387  *
03388  *  A typical implementation of <code>hash</code> is based on the
03389  *  object's data while <code>eql?</code> is usually aliased to the overridden
03390  *  <code>==</code> method:
03391  *
03392  *    class Book
03393  *      attr_reader :author, :title
03394  *
03395  *      def initialize(author, title)
03396  *        @author = author
03397  *        @title = title
03398  *      end
03399  *
03400  *      def ==(other)
03401  *        self.class === other and
03402  *          other.author == @author and
03403  *          other.title == @title
03404  *      end
03405  *
03406  *      alias eql? ==
03407  *
03408  *      def hash
03409  *        @author.hash ^ @title.hash # XOR
03410  *      end
03411  *    end
03412  *
03413  *    book1 = Book.new 'matz', 'Ruby in a Nutshell'
03414  *    book2 = Book.new 'matz', 'Ruby in a Nutshell'
03415  *
03416  *    reviews = {}
03417  *
03418  *    reviews[book1] = 'Great reference!'
03419  *    reviews[book2] = 'Nice and compact!'
03420  *
03421  *    reviews.length #=> 1
03422  *
03423  *  See also Object#hash and Object#eql?
03424  */
03425 
03426 void
03427 Init_Hash(void)
03428 {
03429 #undef rb_intern
03430 #define rb_intern(str) rb_intern_const(str)
03431 
03432     id_hash = rb_intern("hash");
03433     id_yield = rb_intern("yield");
03434     id_default = rb_intern("default");
03435 
03436     rb_cHash = rb_define_class("Hash", rb_cObject);
03437 
03438     rb_include_module(rb_cHash, rb_mEnumerable);
03439 
03440     rb_define_alloc_func(rb_cHash, empty_hash_alloc);
03441     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
03442     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
03443     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
03444     rb_define_method(rb_cHash,"initialize_copy", rb_hash_initialize_copy, 1);
03445     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
03446 
03447     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
03448     rb_define_method(rb_cHash,"to_h", rb_hash_to_h, 0);
03449     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
03450     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
03451     rb_define_alias(rb_cHash, "to_s", "inspect");
03452 
03453     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
03454     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
03455     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
03456     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
03457     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
03458     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
03459     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
03460     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
03461     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
03462     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
03463     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
03464     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
03465     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
03466     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
03467     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
03468     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
03469 
03470     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
03471     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
03472     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
03473     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
03474 
03475     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
03476     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
03477     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
03478 
03479     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
03480     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
03481     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
03482     rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
03483     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
03484     rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
03485     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
03486     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
03487     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
03488     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
03489     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
03490     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
03491     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
03492     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
03493     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
03494     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
03495     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
03496 
03497     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
03498     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
03499     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
03500     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
03501     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
03502     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
03503 
03504     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
03505     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
03506 
03507     /* Document-class: ENV
03508      *
03509      * ENV is a hash-like accessor for environment variables.
03510      */
03511 
03512     /*
03513      * Hack to get RDoc to regard ENV as a class:
03514      * envtbl = rb_define_class("ENV", rb_cObject);
03515      */
03516     origenviron = environ;
03517     envtbl = rb_obj_alloc(rb_cObject);
03518     rb_extend_object(envtbl, rb_mEnumerable);
03519 
03520     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
03521     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
03522     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
03523     rb_define_singleton_method(envtbl,"store", env_aset, 2);
03524     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
03525     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
03526     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
03527     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
03528     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
03529     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
03530     rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
03531     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
03532     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
03533     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
03534     rb_define_singleton_method(envtbl,"select", env_select, 0);
03535     rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
03536     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
03537     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
03538     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
03539     rb_define_singleton_method(envtbl,"update", env_update, 1);
03540     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
03541     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
03542     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
03543     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
03544     rb_define_singleton_method(envtbl,"key", env_key, 1);
03545     rb_define_singleton_method(envtbl,"index", env_index, 1);
03546     rb_define_singleton_method(envtbl,"size", env_size, 0);
03547     rb_define_singleton_method(envtbl,"length", env_size, 0);
03548     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
03549     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
03550     rb_define_singleton_method(envtbl,"values", env_values, 0);
03551     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
03552     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
03553     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
03554     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
03555     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
03556     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
03557     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
03558     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
03559     rb_define_singleton_method(envtbl,"to_h", env_to_hash, 0);
03560     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
03561     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
03562 
03563     /*
03564      * ENV is a Hash-like accessor for environment variables.
03565      *
03566      * See ENV (the class) for more details.
03567      */
03568     rb_define_global_const("ENV", envtbl);
03569 }
03570