Ruby  2.0.0p247(2013-06-27revision41674)
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---Associates the value given by
01176  *  <i>value</i> with the key given by <i>key</i>.
01177  *  <i>key</i> should not have its value changed while it is in
01178  *  use as a key (a <code>String</code> passed as a key will be
01179  *  duplicated and frozen).
01180  *
01181  *     h = { "a" => 100, "b" => 200 }
01182  *     h["a"] = 9
01183  *     h["c"] = 4
01184  *     h   #=> {"a"=>9, "b"=>200, "c"=>4}
01185  *
01186  */
01187 
01188 VALUE
01189 rb_hash_aset(VALUE hash, VALUE key, VALUE val)
01190 {
01191     int iter_lev = RHASH_ITER_LEV(hash);
01192     st_table *tbl = RHASH(hash)->ntbl;
01193 
01194     rb_hash_modify(hash);
01195     if (!tbl) {
01196         if (iter_lev > 0) no_new_key();
01197         tbl = RHASH_TBL(hash);
01198     }
01199     if (tbl->type == &identhash || rb_obj_class(key) != rb_cString) {
01200         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset, val);
01201     }
01202     else {
01203         RHASH_UPDATE_ITER(hash, iter_lev, key, hash_aset_str, val);
01204     }
01205     return val;
01206 }
01207 
01208 static int
01209 replace_i(VALUE key, VALUE val, VALUE hash)
01210 {
01211     rb_hash_aset(hash, key, val);
01212 
01213     return ST_CONTINUE;
01214 }
01215 
01216 static VALUE
01217 rb_hash_initialize_copy(VALUE hash, VALUE hash2)
01218 {
01219     rb_hash_modify_check(hash);
01220     hash2 = to_hash(hash2);
01221 
01222     Check_Type(hash2, T_HASH);
01223 
01224     if (!RHASH_EMPTY_P(hash2)) {
01225         RHASH(hash)->ntbl = st_copy(RHASH(hash2)->ntbl);
01226         rb_hash_rehash(hash);
01227     }
01228 
01229     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
01230         FL_SET(hash, HASH_PROC_DEFAULT);
01231     }
01232     else {
01233         FL_UNSET(hash, HASH_PROC_DEFAULT);
01234     }
01235     RHASH_IFNONE(hash) = RHASH_IFNONE(hash2);
01236 
01237     return hash;
01238 }
01239 
01240 /*
01241  *  call-seq:
01242  *     hsh.replace(other_hash) -> hsh
01243  *
01244  *  Replaces the contents of <i>hsh</i> with the contents of
01245  *  <i>other_hash</i>.
01246  *
01247  *     h = { "a" => 100, "b" => 200 }
01248  *     h.replace({ "c" => 300, "d" => 400 })   #=> {"c"=>300, "d"=>400}
01249  *
01250  */
01251 
01252 static VALUE
01253 rb_hash_replace(VALUE hash, VALUE hash2)
01254 {
01255     rb_hash_modify_check(hash);
01256     hash2 = to_hash(hash2);
01257     if (hash == hash2) return hash;
01258     rb_hash_clear(hash);
01259     if (RHASH(hash2)->ntbl) {
01260         rb_hash_tbl(hash);
01261         RHASH(hash)->ntbl->type = RHASH(hash2)->ntbl->type;
01262     }
01263     rb_hash_foreach(hash2, replace_i, hash);
01264     RHASH_IFNONE(hash) = RHASH_IFNONE(hash2);
01265     if (FL_TEST(hash2, HASH_PROC_DEFAULT)) {
01266         FL_SET(hash, HASH_PROC_DEFAULT);
01267     }
01268     else {
01269         FL_UNSET(hash, HASH_PROC_DEFAULT);
01270     }
01271 
01272     return hash;
01273 }
01274 
01275 /*
01276  *  call-seq:
01277  *     hsh.length    ->  fixnum
01278  *     hsh.size      ->  fixnum
01279  *
01280  *  Returns the number of key-value pairs in the hash.
01281  *
01282  *     h = { "d" => 100, "a" => 200, "v" => 300, "e" => 400 }
01283  *     h.length        #=> 4
01284  *     h.delete("a")   #=> 200
01285  *     h.length        #=> 3
01286  */
01287 
01288 static VALUE
01289 rb_hash_size(VALUE hash)
01290 {
01291     if (!RHASH(hash)->ntbl)
01292         return INT2FIX(0);
01293     return INT2FIX(RHASH(hash)->ntbl->num_entries);
01294 }
01295 
01296 
01297 /*
01298  *  call-seq:
01299  *     hsh.empty?    -> true or false
01300  *
01301  *  Returns <code>true</code> if <i>hsh</i> contains no key-value pairs.
01302  *
01303  *     {}.empty?   #=> true
01304  *
01305  */
01306 
01307 static VALUE
01308 rb_hash_empty_p(VALUE hash)
01309 {
01310     return RHASH_EMPTY_P(hash) ? Qtrue : Qfalse;
01311 }
01312 
01313 static int
01314 each_value_i(VALUE key, VALUE value)
01315 {
01316     rb_yield(value);
01317     return ST_CONTINUE;
01318 }
01319 
01320 /*
01321  *  call-seq:
01322  *     hsh.each_value {| value | block } -> hsh
01323  *     hsh.each_value                    -> an_enumerator
01324  *
01325  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the
01326  *  value as a parameter.
01327  *
01328  *  If no block is given, an enumerator is returned instead.
01329  *
01330  *     h = { "a" => 100, "b" => 200 }
01331  *     h.each_value {|value| puts value }
01332  *
01333  *  <em>produces:</em>
01334  *
01335  *     100
01336  *     200
01337  */
01338 
01339 static VALUE
01340 rb_hash_each_value(VALUE hash)
01341 {
01342     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01343     rb_hash_foreach(hash, each_value_i, 0);
01344     return hash;
01345 }
01346 
01347 static int
01348 each_key_i(VALUE key, VALUE value)
01349 {
01350     rb_yield(key);
01351     return ST_CONTINUE;
01352 }
01353 
01354 /*
01355  *  call-seq:
01356  *     hsh.each_key {| key | block } -> hsh
01357  *     hsh.each_key                  -> an_enumerator
01358  *
01359  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key
01360  *  as a parameter.
01361  *
01362  *  If no block is given, an enumerator is returned instead.
01363  *
01364  *     h = { "a" => 100, "b" => 200 }
01365  *     h.each_key {|key| puts key }
01366  *
01367  *  <em>produces:</em>
01368  *
01369  *     a
01370  *     b
01371  */
01372 static VALUE
01373 rb_hash_each_key(VALUE hash)
01374 {
01375     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01376     rb_hash_foreach(hash, each_key_i, 0);
01377     return hash;
01378 }
01379 
01380 static int
01381 each_pair_i(VALUE key, VALUE value)
01382 {
01383     rb_yield(rb_assoc_new(key, value));
01384     return ST_CONTINUE;
01385 }
01386 
01387 /*
01388  *  call-seq:
01389  *     hsh.each      {| key, value | block } -> hsh
01390  *     hsh.each_pair {| key, value | block } -> hsh
01391  *     hsh.each                              -> an_enumerator
01392  *     hsh.each_pair                         -> an_enumerator
01393  *
01394  *  Calls <i>block</i> once for each key in <i>hsh</i>, passing the key-value
01395  *  pair as parameters.
01396  *
01397  *  If no block is given, an enumerator is returned instead.
01398  *
01399  *     h = { "a" => 100, "b" => 200 }
01400  *     h.each {|key, value| puts "#{key} is #{value}" }
01401  *
01402  *  <em>produces:</em>
01403  *
01404  *     a is 100
01405  *     b is 200
01406  *
01407  */
01408 
01409 static VALUE
01410 rb_hash_each_pair(VALUE hash)
01411 {
01412     RETURN_SIZED_ENUMERATOR(hash, 0, 0, rb_hash_size);
01413     rb_hash_foreach(hash, each_pair_i, 0);
01414     return hash;
01415 }
01416 
01417 static int
01418 to_a_i(VALUE key, VALUE value, VALUE ary)
01419 {
01420     rb_ary_push(ary, rb_assoc_new(key, value));
01421     return ST_CONTINUE;
01422 }
01423 
01424 /*
01425  *  call-seq:
01426  *     hsh.to_a -> array
01427  *
01428  *  Converts <i>hsh</i> to a nested array of <code>[</code> <i>key,
01429  *  value</i> <code>]</code> arrays.
01430  *
01431  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01432  *     h.to_a   #=> [["c", 300], ["a", 100], ["d", 400]]
01433  */
01434 
01435 static VALUE
01436 rb_hash_to_a(VALUE hash)
01437 {
01438     VALUE ary;
01439 
01440     ary = rb_ary_new();
01441     rb_hash_foreach(hash, to_a_i, ary);
01442     OBJ_INFECT(ary, hash);
01443 
01444     return ary;
01445 }
01446 
01447 static int
01448 inspect_i(VALUE key, VALUE value, VALUE str)
01449 {
01450     VALUE str2;
01451 
01452     str2 = rb_inspect(key);
01453     if (RSTRING_LEN(str) > 1) {
01454         rb_str_buf_cat_ascii(str, ", ");
01455     }
01456     else {
01457         rb_enc_copy(str, str2);
01458     }
01459     rb_str_buf_append(str, str2);
01460     OBJ_INFECT(str, str2);
01461     rb_str_buf_cat_ascii(str, "=>");
01462     str2 = rb_inspect(value);
01463     rb_str_buf_append(str, str2);
01464     OBJ_INFECT(str, str2);
01465 
01466     return ST_CONTINUE;
01467 }
01468 
01469 static VALUE
01470 inspect_hash(VALUE hash, VALUE dummy, int recur)
01471 {
01472     VALUE str;
01473 
01474     if (recur) return rb_usascii_str_new2("{...}");
01475     str = rb_str_buf_new2("{");
01476     rb_hash_foreach(hash, inspect_i, str);
01477     rb_str_buf_cat2(str, "}");
01478     OBJ_INFECT(str, hash);
01479 
01480     return str;
01481 }
01482 
01483 /*
01484  * call-seq:
01485  *   hsh.to_s     -> string
01486  *   hsh.inspect  -> string
01487  *
01488  * Return the contents of this hash as a string.
01489  *
01490  *     h = { "c" => 300, "a" => 100, "d" => 400, "c" => 300  }
01491  *     h.to_s   #=> "{\"c\"=>300, \"a\"=>100, \"d\"=>400}"
01492  */
01493 
01494 static VALUE
01495 rb_hash_inspect(VALUE hash)
01496 {
01497     if (RHASH_EMPTY_P(hash))
01498         return rb_usascii_str_new2("{}");
01499     return rb_exec_recursive(inspect_hash, hash, 0);
01500 }
01501 
01502 /*
01503  * call-seq:
01504  *    hsh.to_hash   => hsh
01505  *
01506  * Returns +self+.
01507  */
01508 
01509 static VALUE
01510 rb_hash_to_hash(VALUE hash)
01511 {
01512     return hash;
01513 }
01514 
01515 /*
01516  *  call-seq:
01517  *     hsh.to_h     -> hsh or new_hash
01518  *
01519  *  Returns +self+. If called on a subclass of Hash, converts
01520  *  the receiver to a Hash object.
01521  */
01522 
01523 static VALUE
01524 rb_hash_to_h(VALUE hash)
01525 {
01526     if (rb_obj_class(hash) != rb_cHash) {
01527         VALUE ret = rb_hash_new();
01528         if (!RHASH_EMPTY_P(hash))
01529             RHASH(ret)->ntbl = st_copy(RHASH(hash)->ntbl);
01530         if (FL_TEST(hash, HASH_PROC_DEFAULT)) {
01531             FL_SET(ret, HASH_PROC_DEFAULT);
01532         }
01533         RHASH_IFNONE(ret) = RHASH_IFNONE(hash);
01534         return ret;
01535     }
01536     return hash;
01537 }
01538 
01539 static int
01540 keys_i(VALUE key, VALUE value, VALUE ary)
01541 {
01542     rb_ary_push(ary, key);
01543     return ST_CONTINUE;
01544 }
01545 
01546 /*
01547  *  call-seq:
01548  *     hsh.keys    -> array
01549  *
01550  *  Returns a new array populated with the keys from this hash. See also
01551  *  <code>Hash#values</code>.
01552  *
01553  *     h = { "a" => 100, "b" => 200, "c" => 300, "d" => 400 }
01554  *     h.keys   #=> ["a", "b", "c", "d"]
01555  *
01556  */
01557 
01558 static VALUE
01559 rb_hash_keys(VALUE hash)
01560 {
01561     VALUE ary;
01562 
01563     ary = rb_ary_new();
01564     rb_hash_foreach(hash, keys_i, ary);
01565 
01566     return ary;
01567 }
01568 
01569 static int
01570 values_i(VALUE key, VALUE value, VALUE ary)
01571 {
01572     rb_ary_push(ary, value);
01573     return ST_CONTINUE;
01574 }
01575 
01576 /*
01577  *  call-seq:
01578  *     hsh.values    -> array
01579  *
01580  *  Returns a new array populated with the values from <i>hsh</i>. See
01581  *  also <code>Hash#keys</code>.
01582  *
01583  *     h = { "a" => 100, "b" => 200, "c" => 300 }
01584  *     h.values   #=> [100, 200, 300]
01585  *
01586  */
01587 
01588 static VALUE
01589 rb_hash_values(VALUE hash)
01590 {
01591     VALUE ary;
01592 
01593     ary = rb_ary_new();
01594     rb_hash_foreach(hash, values_i, ary);
01595 
01596     return ary;
01597 }
01598 
01599 /*
01600  *  call-seq:
01601  *     hsh.has_key?(key)    -> true or false
01602  *     hsh.include?(key)    -> true or false
01603  *     hsh.key?(key)        -> true or false
01604  *     hsh.member?(key)     -> true or false
01605  *
01606  *  Returns <code>true</code> if the given key is present in <i>hsh</i>.
01607  *
01608  *     h = { "a" => 100, "b" => 200 }
01609  *     h.has_key?("a")   #=> true
01610  *     h.has_key?("z")   #=> false
01611  *
01612  */
01613 
01614 static VALUE
01615 rb_hash_has_key(VALUE hash, VALUE key)
01616 {
01617     if (!RHASH(hash)->ntbl)
01618         return Qfalse;
01619     if (st_lookup(RHASH(hash)->ntbl, key, 0)) {
01620         return Qtrue;
01621     }
01622     return Qfalse;
01623 }
01624 
01625 static int
01626 rb_hash_search_value(VALUE key, VALUE value, VALUE arg)
01627 {
01628     VALUE *data = (VALUE *)arg;
01629 
01630     if (rb_equal(value, data[1])) {
01631         data[0] = Qtrue;
01632         return ST_STOP;
01633     }
01634     return ST_CONTINUE;
01635 }
01636 
01637 /*
01638  *  call-seq:
01639  *     hsh.has_value?(value)    -> true or false
01640  *     hsh.value?(value)        -> true or false
01641  *
01642  *  Returns <code>true</code> if the given value is present for some key
01643  *  in <i>hsh</i>.
01644  *
01645  *     h = { "a" => 100, "b" => 200 }
01646  *     h.has_value?(100)   #=> true
01647  *     h.has_value?(999)   #=> false
01648  */
01649 
01650 static VALUE
01651 rb_hash_has_value(VALUE hash, VALUE val)
01652 {
01653     VALUE data[2];
01654 
01655     data[0] = Qfalse;
01656     data[1] = val;
01657     rb_hash_foreach(hash, rb_hash_search_value, (VALUE)data);
01658     return data[0];
01659 }
01660 
01661 struct equal_data {
01662     VALUE result;
01663     st_table *tbl;
01664     int eql;
01665 };
01666 
01667 static int
01668 eql_i(VALUE key, VALUE val1, VALUE arg)
01669 {
01670     struct equal_data *data = (struct equal_data *)arg;
01671     st_data_t val2;
01672 
01673     if (!st_lookup(data->tbl, key, &val2)) {
01674         data->result = Qfalse;
01675         return ST_STOP;
01676     }
01677     if (!(data->eql ? rb_eql(val1, (VALUE)val2) : (int)rb_equal(val1, (VALUE)val2))) {
01678         data->result = Qfalse;
01679         return ST_STOP;
01680     }
01681     return ST_CONTINUE;
01682 }
01683 
01684 static VALUE
01685 recursive_eql(VALUE hash, VALUE dt, int recur)
01686 {
01687     struct equal_data *data;
01688 
01689     if (recur) return Qtrue;    /* Subtle! */
01690     data = (struct equal_data*)dt;
01691     data->result = Qtrue;
01692     rb_hash_foreach(hash, eql_i, dt);
01693 
01694     return data->result;
01695 }
01696 
01697 static VALUE
01698 hash_equal(VALUE hash1, VALUE hash2, int eql)
01699 {
01700     struct equal_data data;
01701 
01702     if (hash1 == hash2) return Qtrue;
01703     if (!RB_TYPE_P(hash2, T_HASH)) {
01704         if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
01705             return Qfalse;
01706         }
01707         if (eql)
01708             return rb_eql(hash2, hash1);
01709         else
01710             return rb_equal(hash2, hash1);
01711     }
01712     if (RHASH_SIZE(hash1) != RHASH_SIZE(hash2))
01713         return Qfalse;
01714     if (!RHASH(hash1)->ntbl || !RHASH(hash2)->ntbl)
01715         return Qtrue;
01716     if (RHASH(hash1)->ntbl->type != RHASH(hash2)->ntbl->type)
01717         return Qfalse;
01718 #if 0
01719     if (!(rb_equal(RHASH_IFNONE(hash1), RHASH_IFNONE(hash2)) &&
01720           FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT)))
01721         return Qfalse;
01722 #endif
01723 
01724     data.tbl = RHASH(hash2)->ntbl;
01725     data.eql = eql;
01726     return rb_exec_recursive_paired(recursive_eql, hash1, hash2, (VALUE)&data);
01727 }
01728 
01729 /*
01730  *  call-seq:
01731  *     hsh == other_hash    -> true or false
01732  *
01733  *  Equality---Two hashes are equal if they each contain the same number
01734  *  of keys and if each key-value pair is equal to (according to
01735  *  <code>Object#==</code>) the corresponding elements in the other
01736  *  hash.
01737  *
01738  *     h1 = { "a" => 1, "c" => 2 }
01739  *     h2 = { 7 => 35, "c" => 2, "a" => 1 }
01740  *     h3 = { "a" => 1, "c" => 2, 7 => 35 }
01741  *     h4 = { "a" => 1, "d" => 2, "f" => 35 }
01742  *     h1 == h2   #=> false
01743  *     h2 == h3   #=> true
01744  *     h3 == h4   #=> false
01745  *
01746  */
01747 
01748 static VALUE
01749 rb_hash_equal(VALUE hash1, VALUE hash2)
01750 {
01751     return hash_equal(hash1, hash2, FALSE);
01752 }
01753 
01754 /*
01755  *  call-seq:
01756  *     hash.eql?(other)  -> true or false
01757  *
01758  *  Returns <code>true</code> if <i>hash</i> and <i>other</i> are
01759  *  both hashes with the same content.
01760  */
01761 
01762 static VALUE
01763 rb_hash_eql(VALUE hash1, VALUE hash2)
01764 {
01765     return hash_equal(hash1, hash2, TRUE);
01766 }
01767 
01768 static int
01769 hash_i(VALUE key, VALUE val, VALUE arg)
01770 {
01771     st_index_t *hval = (st_index_t *)arg;
01772     st_index_t hdata[2];
01773 
01774     hdata[0] = rb_hash(key);
01775     hdata[1] = rb_hash(val);
01776     *hval ^= st_hash(hdata, sizeof(hdata), 0);
01777     return ST_CONTINUE;
01778 }
01779 
01780 static VALUE
01781 recursive_hash(VALUE hash, VALUE dummy, int recur)
01782 {
01783     st_index_t hval;
01784 
01785     if (!RHASH(hash)->ntbl)
01786         return LONG2FIX(0);
01787     hval = RHASH(hash)->ntbl->num_entries;
01788     if (!hval) return LONG2FIX(0);
01789     if (recur)
01790         hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval);
01791     else
01792         rb_hash_foreach(hash, hash_i, (VALUE)&hval);
01793     hval = rb_hash_end(hval);
01794     return INT2FIX(hval);
01795 }
01796 
01797 /*
01798  *  call-seq:
01799  *     hsh.hash   -> fixnum
01800  *
01801  *  Compute a hash-code for this hash. Two hashes with the same content
01802  *  will have the same hash code (and will compare using <code>eql?</code>).
01803  */
01804 
01805 static VALUE
01806 rb_hash_hash(VALUE hash)
01807 {
01808     return rb_exec_recursive_outer(recursive_hash, hash, 0);
01809 }
01810 
01811 static int
01812 rb_hash_invert_i(VALUE key, VALUE value, VALUE hash)
01813 {
01814     rb_hash_aset(hash, value, key);
01815     return ST_CONTINUE;
01816 }
01817 
01818 /*
01819  *  call-seq:
01820  *     hsh.invert -> new_hash
01821  *
01822  *  Returns a new hash created by using <i>hsh</i>'s values as keys, and
01823  *  the keys as values.
01824  *
01825  *     h = { "n" => 100, "m" => 100, "y" => 300, "d" => 200, "a" => 0 }
01826  *     h.invert   #=> {0=>"a", 100=>"m", 200=>"d", 300=>"y"}
01827  *
01828  */
01829 
01830 static VALUE
01831 rb_hash_invert(VALUE hash)
01832 {
01833     VALUE h = rb_hash_new();
01834 
01835     rb_hash_foreach(hash, rb_hash_invert_i, h);
01836     return h;
01837 }
01838 
01839 static int
01840 rb_hash_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
01841 {
01842     *value = arg;
01843     return ST_CONTINUE;
01844 }
01845 
01846 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_callback)
01847 
01848 static int
01849 rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
01850 {
01851     RHASH_UPDATE(hash, key, rb_hash_update_callback, value);
01852     return ST_CONTINUE;
01853 }
01854 
01855 static int
01856 rb_hash_update_block_callback(st_data_t *key, st_data_t *value, st_data_t arg, int existing)
01857 {
01858     VALUE newvalue = (VALUE)arg;
01859     if (existing) {
01860         newvalue = rb_yield_values(3, (VALUE)*key, (VALUE)*value, newvalue);
01861     }
01862     *value = (st_data_t)newvalue;
01863     return ST_CONTINUE;
01864 }
01865 
01866 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_block_callback)
01867 
01868 static int
01869 rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
01870 {
01871     RHASH_UPDATE(hash, key, rb_hash_update_block_callback, value);
01872     return ST_CONTINUE;
01873 }
01874 
01875 /*
01876  *  call-seq:
01877  *     hsh.merge!(other_hash)                                 -> hsh
01878  *     hsh.update(other_hash)                                 -> hsh
01879  *     hsh.merge!(other_hash){|key, oldval, newval| block}    -> hsh
01880  *     hsh.update(other_hash){|key, oldval, newval| block}    -> hsh
01881  *
01882  *  Adds the contents of _other_hash_ to _hsh_.  If no block is specified,
01883  *  entries with duplicate keys are overwritten with the values from
01884  *  _other_hash_, otherwise the value of each duplicate key is determined by
01885  *  calling the block with the key, its value in _hsh_ and its value in
01886  *  _other_hash_.
01887  *
01888  *     h1 = { "a" => 100, "b" => 200 }
01889  *     h2 = { "b" => 254, "c" => 300 }
01890  *     h1.merge!(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
01891  *
01892  *     h1 = { "a" => 100, "b" => 200 }
01893  *     h2 = { "b" => 254, "c" => 300 }
01894  *     h1.merge!(h2) { |key, v1, v2| v1 }
01895  *                     #=> {"a"=>100, "b"=>200, "c"=>300}
01896  */
01897 
01898 static VALUE
01899 rb_hash_update(VALUE hash1, VALUE hash2)
01900 {
01901     rb_hash_modify(hash1);
01902     hash2 = to_hash(hash2);
01903     if (rb_block_given_p()) {
01904         rb_hash_foreach(hash2, rb_hash_update_block_i, hash1);
01905     }
01906     else {
01907         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
01908     }
01909     return hash1;
01910 }
01911 
01912 struct update_arg {
01913     VALUE hash;
01914     VALUE value;
01915     rb_hash_update_func *func;
01916 };
01917 
01918 static int
01919 rb_hash_update_func_callback(st_data_t *key, st_data_t *value, st_data_t arg0, int existing)
01920 {
01921     struct update_arg *arg = (struct update_arg *)arg0;
01922     VALUE newvalue = arg->value;
01923     if (existing) {
01924         newvalue = (*arg->func)((VALUE)*key, (VALUE)*value, newvalue);
01925     }
01926     *value = (st_data_t)newvalue;
01927     return ST_CONTINUE;
01928 }
01929 
01930 static NOINSERT_UPDATE_CALLBACK(rb_hash_update_func_callback)
01931 
01932 static int
01933 rb_hash_update_func_i(VALUE key, VALUE value, VALUE arg0)
01934 {
01935     struct update_arg *arg = (struct update_arg *)arg0;
01936     VALUE hash = arg->hash;
01937 
01938     arg->value = value;
01939     RHASH_UPDATE(hash, key, rb_hash_update_func_callback, arg);
01940     return ST_CONTINUE;
01941 }
01942 
01943 VALUE
01944 rb_hash_update_by(VALUE hash1, VALUE hash2, rb_hash_update_func *func)
01945 {
01946     rb_hash_modify(hash1);
01947     hash2 = to_hash(hash2);
01948     if (func) {
01949         struct update_arg arg;
01950         arg.hash = hash1;
01951         arg.func = func;
01952         rb_hash_foreach(hash2, rb_hash_update_func_i, (VALUE)&arg);
01953     }
01954     else {
01955         rb_hash_foreach(hash2, rb_hash_update_i, hash1);
01956     }
01957     return hash1;
01958 }
01959 
01960 /*
01961  *  call-seq:
01962  *     hsh.merge(other_hash)                              -> new_hash
01963  *     hsh.merge(other_hash){|key, oldval, newval| block} -> new_hash
01964  *
01965  *  Returns a new hash containing the contents of <i>other_hash</i> and
01966  *  the contents of <i>hsh</i>. If no block is specified, the value for
01967  *  entries with duplicate keys will be that of <i>other_hash</i>. Otherwise
01968  *  the value for each duplicate key is determined by calling the block
01969  *  with the key, its value in <i>hsh</i> and its value in <i>other_hash</i>.
01970  *
01971  *     h1 = { "a" => 100, "b" => 200 }
01972  *     h2 = { "b" => 254, "c" => 300 }
01973  *     h1.merge(h2)   #=> {"a"=>100, "b"=>254, "c"=>300}
01974  *     h1.merge(h2){|key, oldval, newval| newval - oldval}
01975  *                    #=> {"a"=>100, "b"=>54,  "c"=>300}
01976  *     h1             #=> {"a"=>100, "b"=>200}
01977  *
01978  */
01979 
01980 static VALUE
01981 rb_hash_merge(VALUE hash1, VALUE hash2)
01982 {
01983     return rb_hash_update(rb_obj_dup(hash1), hash2);
01984 }
01985 
01986 static int
01987 assoc_i(VALUE key, VALUE val, VALUE arg)
01988 {
01989     VALUE *args = (VALUE *)arg;
01990 
01991     if (RTEST(rb_equal(args[0], key))) {
01992         args[1] = rb_assoc_new(key, val);
01993         return ST_STOP;
01994     }
01995     return ST_CONTINUE;
01996 }
01997 
01998 /*
01999  *  call-seq:
02000  *     hash.assoc(obj)   ->  an_array  or  nil
02001  *
02002  *  Searches through the hash comparing _obj_ with the key using <code>==</code>.
02003  *  Returns the key-value pair (two elements array) or +nil+
02004  *  if no match is found.  See <code>Array#assoc</code>.
02005  *
02006  *     h = {"colors"  => ["red", "blue", "green"],
02007  *          "letters" => ["a", "b", "c" ]}
02008  *     h.assoc("letters")  #=> ["letters", ["a", "b", "c"]]
02009  *     h.assoc("foo")      #=> nil
02010  */
02011 
02012 VALUE
02013 rb_hash_assoc(VALUE hash, VALUE obj)
02014 {
02015     VALUE args[2];
02016 
02017     args[0] = obj;
02018     args[1] = Qnil;
02019     rb_hash_foreach(hash, assoc_i, (VALUE)args);
02020     return args[1];
02021 }
02022 
02023 static int
02024 rassoc_i(VALUE key, VALUE val, VALUE arg)
02025 {
02026     VALUE *args = (VALUE *)arg;
02027 
02028     if (RTEST(rb_equal(args[0], val))) {
02029         args[1] = rb_assoc_new(key, val);
02030         return ST_STOP;
02031     }
02032     return ST_CONTINUE;
02033 }
02034 
02035 /*
02036  *  call-seq:
02037  *     hash.rassoc(obj) -> an_array or nil
02038  *
02039  *  Searches through the hash comparing _obj_ with the value using <code>==</code>.
02040  *  Returns the first key-value pair (two-element array) that matches. See
02041  *  also <code>Array#rassoc</code>.
02042  *
02043  *     a = {1=> "one", 2 => "two", 3 => "three", "ii" => "two"}
02044  *     a.rassoc("two")    #=> [2, "two"]
02045  *     a.rassoc("four")   #=> nil
02046  */
02047 
02048 VALUE
02049 rb_hash_rassoc(VALUE hash, VALUE obj)
02050 {
02051     VALUE args[2];
02052 
02053     args[0] = obj;
02054     args[1] = Qnil;
02055     rb_hash_foreach(hash, rassoc_i, (VALUE)args);
02056     return args[1];
02057 }
02058 
02059 /*
02060  *  call-seq:
02061  *     hash.flatten -> an_array
02062  *     hash.flatten(level) -> an_array
02063  *
02064  *  Returns a new array that is a one-dimensional flattening of this
02065  *  hash. That is, for every key or value that is an array, extract
02066  *  its elements into the new array.  Unlike Array#flatten, this
02067  *  method does not flatten recursively by default.  The optional
02068  *  <i>level</i> argument determines the level of recursion to flatten.
02069  *
02070  *     a =  {1=> "one", 2 => [2,"two"], 3 => "three"}
02071  *     a.flatten    # => [1, "one", 2, [2, "two"], 3, "three"]
02072  *     a.flatten(2) # => [1, "one", 2, 2, "two", 3, "three"]
02073  */
02074 
02075 static VALUE
02076 rb_hash_flatten(int argc, VALUE *argv, VALUE hash)
02077 {
02078     VALUE ary, tmp;
02079 
02080     ary = rb_hash_to_a(hash);
02081     if (argc == 0) {
02082         argc = 1;
02083         tmp = INT2FIX(1);
02084         argv = &tmp;
02085     }
02086     rb_funcall2(ary, rb_intern("flatten!"), argc, argv);
02087     return ary;
02088 }
02089 
02090 /*
02091  *  call-seq:
02092  *     hsh.compare_by_identity -> hsh
02093  *
02094  *  Makes <i>hsh</i> compare its keys by their identity, i.e. it
02095  *  will consider exact same objects as same keys.
02096  *
02097  *     h1 = { "a" => 100, "b" => 200, :c => "c" }
02098  *     h1["a"]        #=> 100
02099  *     h1.compare_by_identity
02100  *     h1.compare_by_identity? #=> true
02101  *     h1["a"]        #=> nil  # different objects.
02102  *     h1[:c]         #=> "c"  # same symbols are all same.
02103  *
02104  */
02105 
02106 static VALUE
02107 rb_hash_compare_by_id(VALUE hash)
02108 {
02109     rb_hash_modify(hash);
02110     RHASH(hash)->ntbl->type = &identhash;
02111     rb_hash_rehash(hash);
02112     return hash;
02113 }
02114 
02115 /*
02116  *  call-seq:
02117  *     hsh.compare_by_identity? -> true or false
02118  *
02119  *  Returns <code>true</code> if <i>hsh</i> will compare its keys by
02120  *  their identity.  Also see <code>Hash#compare_by_identity</code>.
02121  *
02122  */
02123 
02124 static VALUE
02125 rb_hash_compare_by_id_p(VALUE hash)
02126 {
02127     if (!RHASH(hash)->ntbl)
02128         return Qfalse;
02129     if (RHASH(hash)->ntbl->type == &identhash) {
02130         return Qtrue;
02131     }
02132     return Qfalse;
02133 }
02134 
02135 static int path_tainted = -1;
02136 
02137 static char **origenviron;
02138 #ifdef _WIN32
02139 #define GET_ENVIRON(e) ((e) = rb_w32_get_environ())
02140 #define FREE_ENVIRON(e) rb_w32_free_environ(e)
02141 static char **my_environ;
02142 #undef environ
02143 #define environ my_environ
02144 #undef getenv
02145 #define getenv(n) rb_w32_ugetenv(n)
02146 #elif defined(__APPLE__)
02147 #undef environ
02148 #define environ (*_NSGetEnviron())
02149 #define GET_ENVIRON(e) (e)
02150 #define FREE_ENVIRON(e)
02151 #else
02152 extern char **environ;
02153 #define GET_ENVIRON(e) (e)
02154 #define FREE_ENVIRON(e)
02155 #endif
02156 #ifdef ENV_IGNORECASE
02157 #define ENVMATCH(s1, s2) (STRCASECMP((s1), (s2)) == 0)
02158 #define ENVNMATCH(s1, s2, n) (STRNCASECMP((s1), (s2), (n)) == 0)
02159 #else
02160 #define ENVMATCH(n1, n2) (strcmp((n1), (n2)) == 0)
02161 #define ENVNMATCH(s1, s2, n) (memcmp((s1), (s2), (n)) == 0)
02162 #endif
02163 
02164 static VALUE
02165 env_str_new(const char *ptr, long len)
02166 {
02167 #ifdef _WIN32
02168     VALUE str = rb_str_conv_enc(rb_str_new(ptr, len), rb_utf8_encoding(), rb_locale_encoding());
02169 #else
02170     VALUE str = rb_locale_str_new(ptr, len);
02171 #endif
02172 
02173     rb_obj_freeze(str);
02174     return str;
02175 }
02176 
02177 static VALUE
02178 env_str_new2(const char *ptr)
02179 {
02180     if (!ptr) return Qnil;
02181     return env_str_new(ptr, strlen(ptr));
02182 }
02183 
02184 static VALUE
02185 env_delete(VALUE obj, VALUE name)
02186 {
02187     char *nam, *val;
02188 
02189     rb_secure(4);
02190     SafeStringValue(name);
02191     nam = RSTRING_PTR(name);
02192     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02193         rb_raise(rb_eArgError, "bad environment variable name");
02194     }
02195     val = getenv(nam);
02196     if (val) {
02197         VALUE value = env_str_new2(val);
02198 
02199         ruby_setenv(nam, 0);
02200         if (ENVMATCH(nam, PATH_ENV)) {
02201             path_tainted = 0;
02202         }
02203         return value;
02204     }
02205     return Qnil;
02206 }
02207 
02208 /*
02209  * call-seq:
02210  *   ENV.delete(name)            -> value
02211  *   ENV.delete(name) { |name| } -> value
02212  *
02213  * Deletes the environment variable with +name+ and returns the value of the
02214  * variable.  If a block is given it will be called when the named environment
02215  * does not exist.
02216  */
02217 static VALUE
02218 env_delete_m(VALUE obj, VALUE name)
02219 {
02220     VALUE val;
02221 
02222     val = env_delete(obj, name);
02223     if (NIL_P(val) && rb_block_given_p()) rb_yield(name);
02224     return val;
02225 }
02226 
02227 static int env_path_tainted(const char *);
02228 
02229 /*
02230  * call-seq:
02231  *   ENV[name] -> value
02232  *
02233  * Retrieves the +value+ for environment variable +name+ as a String.  Returns
02234  * +nil+ if the named variable does not exist.
02235  */
02236 static VALUE
02237 rb_f_getenv(VALUE obj, VALUE name)
02238 {
02239     char *nam, *env;
02240 
02241     rb_secure(4);
02242     SafeStringValue(name);
02243     nam = RSTRING_PTR(name);
02244     if (memchr(nam, '\0', RSTRING_LEN(name))) {
02245         rb_raise(rb_eArgError, "bad environment variable name");
02246     }
02247     env = getenv(nam);
02248     if (env) {
02249         if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env)) {
02250 #ifdef _WIN32
02251             VALUE str = rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02252 #else
02253             VALUE str = rb_filesystem_str_new_cstr(env);
02254 #endif
02255 
02256             rb_obj_freeze(str);
02257             return str;
02258         }
02259         return env_str_new2(env);
02260     }
02261     return Qnil;
02262 }
02263 
02264 /*
02265  * :yield: missing_name
02266  * call-seq:
02267  *   ENV.fetch(name)                        -> value
02268  *   ENV.fetch(name, default)               -> value
02269  *   ENV.fetch(name) { |missing_name| ... } -> value
02270  *
02271  * Retrieves the environment variable +name+.
02272  *
02273  * If the given name does not exist and neither +default+ nor a block a
02274  * provided an IndexError is raised.  If a block is given it is called with
02275  * the missing name to provide a value.  If a default value is given it will
02276  * be returned when no block is given.
02277  */
02278 static VALUE
02279 env_fetch(int argc, VALUE *argv)
02280 {
02281     VALUE key, if_none;
02282     long block_given;
02283     char *nam, *env;
02284 
02285     rb_secure(4);
02286     rb_scan_args(argc, argv, "11", &key, &if_none);
02287     block_given = rb_block_given_p();
02288     if (block_given && argc == 2) {
02289         rb_warn("block supersedes default value argument");
02290     }
02291     SafeStringValue(key);
02292     nam = RSTRING_PTR(key);
02293     if (memchr(nam, '\0', RSTRING_LEN(key))) {
02294         rb_raise(rb_eArgError, "bad environment variable name");
02295     }
02296     env = getenv(nam);
02297     if (!env) {
02298         if (block_given) return rb_yield(key);
02299         if (argc == 1) {
02300             rb_raise(rb_eKeyError, "key not found");
02301         }
02302         return if_none;
02303     }
02304     if (ENVMATCH(nam, PATH_ENV) && !env_path_tainted(env))
02305 #ifdef _WIN32
02306         return rb_str_conv_enc(rb_str_new(env, strlen(env)), rb_utf8_encoding(), rb_filesystem_encoding());
02307 #else
02308         return rb_filesystem_str_new_cstr(env);
02309 #endif
02310     return env_str_new2(env);
02311 }
02312 
02313 static void
02314 path_tainted_p(const char *path)
02315 {
02316     path_tainted = rb_path_check(path)?0:1;
02317 }
02318 
02319 static int
02320 env_path_tainted(const char *path)
02321 {
02322     if (path_tainted < 0) {
02323         path_tainted_p(path);
02324     }
02325     return path_tainted;
02326 }
02327 
02328 int
02329 rb_env_path_tainted(void)
02330 {
02331     if (path_tainted < 0) {
02332         path_tainted_p(getenv(PATH_ENV));
02333     }
02334     return path_tainted;
02335 }
02336 
02337 #if defined(_WIN32) || (defined(HAVE_SETENV) && defined(HAVE_UNSETENV))
02338 #elif defined __sun
02339 static int
02340 in_origenv(const char *str)
02341 {
02342     char **env;
02343     for (env = origenviron; *env; ++env) {
02344         if (*env == str) return 1;
02345     }
02346     return 0;
02347 }
02348 #else
02349 static int
02350 envix(const char *nam)
02351 {
02352     register int i, len = strlen(nam);
02353     char **env;
02354 
02355     env = GET_ENVIRON(environ);
02356     for (i = 0; env[i]; i++) {
02357         if (ENVNMATCH(env[i],nam,len) && env[i][len] == '=')
02358             break;                      /* memcmp must come first to avoid */
02359     }                                   /* potential SEGV's */
02360     FREE_ENVIRON(environ);
02361     return i;
02362 }
02363 #endif
02364 
02365 #if defined(_WIN32)
02366 static size_t
02367 getenvsize(const char* p)
02368 {
02369     const char* porg = p;
02370     while (*p++) p += strlen(p) + 1;
02371     return p - porg + 1;
02372 }
02373 static size_t
02374 getenvblocksize()
02375 {
02376     return (rb_w32_osver() >= 5) ? 32767 : 5120;
02377 }
02378 #endif
02379 
02380 void
02381 ruby_setenv(const char *name, const char *value)
02382 {
02383 #if defined(_WIN32)
02384     VALUE buf;
02385     int failed = 0;
02386     if (strchr(name, '=')) {
02387       fail:
02388         errno = EINVAL;
02389         rb_sys_fail("ruby_setenv");
02390     }
02391     if (value) {
02392         const char* p = GetEnvironmentStringsA();
02393         if (!p) goto fail; /* never happen */
02394         if (strlen(name) + 2 + strlen(value) + getenvsize(p) >= getenvblocksize()) {
02395             goto fail;  /* 2 for '=' & '\0' */
02396         }
02397         buf = rb_sprintf("%s=%s", name, value);
02398     }
02399     else {
02400         buf = rb_sprintf("%s=", name);
02401     }
02402     failed = putenv(RSTRING_PTR(buf));
02403     /* even if putenv() failed, clean up and try to delete the
02404      * variable from the system area. */
02405     rb_str_resize(buf, 0);
02406     if (!value || !*value) {
02407         /* putenv() doesn't handle empty value */
02408         if (!SetEnvironmentVariable(name, value) &&
02409             GetLastError() != ERROR_ENVVAR_NOT_FOUND) goto fail;
02410     }
02411     if (failed) goto fail;
02412 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
02413 #undef setenv
02414 #undef unsetenv
02415     if (value) {
02416         if (setenv(name, value, 1))
02417             rb_sys_fail("setenv");
02418     } else {
02419 #ifdef VOID_UNSETENV
02420         unsetenv(name);
02421 #else
02422         if (unsetenv(name))
02423             rb_sys_fail("unsetenv");
02424 #endif
02425     }
02426 #elif defined __sun
02427     size_t len;
02428     char **env_ptr, *str;
02429     if (strchr(name, '=')) {
02430         errno = EINVAL;
02431         rb_sys_fail("ruby_setenv");
02432     }
02433     len = strlen(name);
02434     for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
02435         if (!strncmp(str, name, len) && str[len] == '=') {
02436             if (!in_origenv(str)) free(str);
02437             while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
02438             break;
02439         }
02440     }
02441     if (value) {
02442         str = malloc(len += strlen(value) + 2);
02443         snprintf(str, len, "%s=%s", name, value);
02444         if (putenv(str))
02445             rb_sys_fail("putenv");
02446     }
02447 #else  /* WIN32 */
02448     size_t len;
02449     int i;
02450     if (strchr(name, '=')) {
02451         errno = EINVAL;
02452         rb_sys_fail("ruby_setenv");
02453     }
02454     i=envix(name);                      /* where does it go? */
02455 
02456     if (environ == origenviron) {       /* need we copy environment? */
02457         int j;
02458         int max;
02459         char **tmpenv;
02460 
02461         for (max = i; environ[max]; max++) ;
02462         tmpenv = ALLOC_N(char*, max+2);
02463         for (j=0; j<max; j++)           /* copy environment */
02464             tmpenv[j] = ruby_strdup(environ[j]);
02465         tmpenv[max] = 0;
02466         environ = tmpenv;               /* tell exec where it is now */
02467     }
02468     if (environ[i]) {
02469         char **envp = origenviron;
02470         while (*envp && *envp != environ[i]) envp++;
02471         if (!*envp)
02472             xfree(environ[i]);
02473         if (!value) {
02474             while (environ[i]) {
02475                 environ[i] = environ[i+1];
02476                 i++;
02477             }
02478             return;
02479         }
02480     }
02481     else {                      /* does not exist yet */
02482         if (!value) return;
02483         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
02484         environ[i+1] = 0;       /* make sure it's null terminated */
02485     }
02486     len = strlen(name) + strlen(value) + 2;
02487     environ[i] = ALLOC_N(char, len);
02488     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
02489 #endif /* WIN32 */
02490 }
02491 
02492 void
02493 ruby_unsetenv(const char *name)
02494 {
02495     ruby_setenv(name, 0);
02496 }
02497 
02498 /*
02499  * call-seq:
02500  *   ENV[name] = value
02501  *   ENV.store(name, value) -> value
02502  *
02503  * Sets the environment variable +name+ to +value+.  If the value given is
02504  * +nil+ the environment variable is deleted.
02505  *
02506  */
02507 static VALUE
02508 env_aset(VALUE obj, VALUE nm, VALUE val)
02509 {
02510     char *name, *value;
02511 
02512     if (rb_safe_level() >= 4) {
02513         rb_raise(rb_eSecurityError, "can't change environment variable");
02514     }
02515 
02516     if (NIL_P(val)) {
02517         env_delete(obj, nm);
02518         return Qnil;
02519     }
02520     StringValue(nm);
02521     StringValue(val);
02522     name = RSTRING_PTR(nm);
02523     value = RSTRING_PTR(val);
02524     if (memchr(name, '\0', RSTRING_LEN(nm)))
02525         rb_raise(rb_eArgError, "bad environment variable name");
02526     if (memchr(value, '\0', RSTRING_LEN(val)))
02527         rb_raise(rb_eArgError, "bad environment variable value");
02528 
02529     ruby_setenv(name, value);
02530     if (ENVMATCH(name, PATH_ENV)) {
02531         if (OBJ_TAINTED(val)) {
02532             /* already tainted, no check */
02533             path_tainted = 1;
02534             return val;
02535         }
02536         else {
02537             path_tainted_p(value);
02538         }
02539     }
02540     return val;
02541 }
02542 
02543 /*
02544  * call-seq:
02545  *   ENV.keys -> Array
02546  *
02547  * Returns every environment variable name in an Array
02548  */
02549 static VALUE
02550 env_keys(void)
02551 {
02552     char **env;
02553     VALUE ary;
02554 
02555     rb_secure(4);
02556     ary = rb_ary_new();
02557     env = GET_ENVIRON(environ);
02558     while (*env) {
02559         char *s = strchr(*env, '=');
02560         if (s) {
02561             rb_ary_push(ary, env_str_new(*env, s-*env));
02562         }
02563         env++;
02564     }
02565     FREE_ENVIRON(environ);
02566     return ary;
02567 }
02568 
02569 static VALUE
02570 rb_env_size(VALUE ehash)
02571 {
02572     char **env;
02573     long cnt = 0;
02574 
02575     rb_secure(4);
02576 
02577     env = GET_ENVIRON(environ);
02578     for (; *env ; ++env) {
02579         if (strchr(*env, '=')) {
02580             cnt++;
02581         }
02582     }
02583     FREE_ENVIRON(environ);
02584     return LONG2FIX(cnt);
02585 }
02586 
02587 /*
02588  * call-seq:
02589  *   ENV.each_key { |name| } -> Hash
02590  *   ENV.each_key            -> Enumerator
02591  *
02592  * Yields each environment variable name.
02593  *
02594  * An Enumerator is returned if no block is given.
02595  */
02596 static VALUE
02597 env_each_key(VALUE ehash)
02598 {
02599     VALUE keys;
02600     long i;
02601 
02602     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02603     keys = env_keys();  /* rb_secure(4); */
02604     for (i=0; i<RARRAY_LEN(keys); i++) {
02605         rb_yield(RARRAY_PTR(keys)[i]);
02606     }
02607     return ehash;
02608 }
02609 
02610 /*
02611  * call-seq:
02612  *   ENV.values -> Array
02613  *
02614  * Returns every environment variable value as an Array
02615  */
02616 static VALUE
02617 env_values(void)
02618 {
02619     VALUE ary;
02620     char **env;
02621 
02622     rb_secure(4);
02623     ary = rb_ary_new();
02624     env = GET_ENVIRON(environ);
02625     while (*env) {
02626         char *s = strchr(*env, '=');
02627         if (s) {
02628             rb_ary_push(ary, env_str_new2(s+1));
02629         }
02630         env++;
02631     }
02632     FREE_ENVIRON(environ);
02633     return ary;
02634 }
02635 
02636 /*
02637  * call-seq:
02638  *   ENV.each_value { |value| } -> Hash
02639  *   ENV.each_value             -> Enumerator
02640  *
02641  * Yields each environment variable +value+.
02642  *
02643  * An Enumerator is returned if no block was given.
02644  */
02645 static VALUE
02646 env_each_value(VALUE ehash)
02647 {
02648     VALUE values;
02649     long i;
02650 
02651     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02652     values = env_values();      /* rb_secure(4); */
02653     for (i=0; i<RARRAY_LEN(values); i++) {
02654         rb_yield(RARRAY_PTR(values)[i]);
02655     }
02656     return ehash;
02657 }
02658 
02659 /*
02660  * call-seq:
02661  *   ENV.each      { |name, value| } -> Hash
02662  *   ENV.each                        -> Enumerator
02663  *   ENV.each_pair { |name, value| } -> Hash
02664  *   ENV.each_pair                   -> Enumerator
02665  *
02666  * Yields each environment variable +name+ and +value+.
02667  *
02668  * If no block is given an Enumerator is returned.
02669  */
02670 static VALUE
02671 env_each_pair(VALUE ehash)
02672 {
02673     char **env;
02674     VALUE ary;
02675     long i;
02676 
02677     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02678 
02679     rb_secure(4);
02680     ary = rb_ary_new();
02681     env = GET_ENVIRON(environ);
02682     while (*env) {
02683         char *s = strchr(*env, '=');
02684         if (s) {
02685             rb_ary_push(ary, env_str_new(*env, s-*env));
02686             rb_ary_push(ary, env_str_new2(s+1));
02687         }
02688         env++;
02689     }
02690     FREE_ENVIRON(environ);
02691 
02692     for (i=0; i<RARRAY_LEN(ary); i+=2) {
02693         rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]));
02694     }
02695     return ehash;
02696 }
02697 
02698 /*
02699  * call-seq:
02700  *   ENV.reject! { |name, value| } -> ENV or nil
02701  *   ENV.reject!                   -> Enumerator
02702  *
02703  * Equivalent to ENV#delete_if but returns +nil+ if no changes were made.
02704  *
02705  * Returns an Enumerator if no block was given.
02706  */
02707 static VALUE
02708 env_reject_bang(VALUE ehash)
02709 {
02710     volatile VALUE keys;
02711     long i;
02712     int del = 0;
02713 
02714     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02715     keys = env_keys();  /* rb_secure(4); */
02716     RBASIC(keys)->klass = 0;
02717     for (i=0; i<RARRAY_LEN(keys); i++) {
02718         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02719         if (!NIL_P(val)) {
02720             if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02721                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02722                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02723                 del++;
02724             }
02725         }
02726     }
02727     if (del == 0) return Qnil;
02728     return envtbl;
02729 }
02730 
02731 /*
02732  * call-seq:
02733  *   ENV.delete_if { |name, value| } -> Hash
02734  *   ENV.delete_if                   -> Enumerator
02735  *
02736  * Deletes every environment variable for which the block evaluates to +true+.
02737  *
02738  * If no block is given an enumerator is returned instead.
02739  */
02740 static VALUE
02741 env_delete_if(VALUE ehash)
02742 {
02743     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02744     env_reject_bang(ehash);
02745     return envtbl;
02746 }
02747 
02748 /*
02749  * call-seq:
02750  *   ENV.values_at(name, ...) -> Array
02751  *
02752  * Returns an array containing the environment variable values associated with
02753  * the given names.  See also ENV.select.
02754  */
02755 static VALUE
02756 env_values_at(int argc, VALUE *argv)
02757 {
02758     VALUE result;
02759     long i;
02760 
02761     rb_secure(4);
02762     result = rb_ary_new();
02763     for (i=0; i<argc; i++) {
02764         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
02765     }
02766     return result;
02767 }
02768 
02769 /*
02770  * call-seq:
02771  *   ENV.select { |name, value| } -> Hash
02772  *   ENV.select                   -> Enumerator
02773  *
02774  * Returns a copy of the environment for entries where the block returns true.
02775  *
02776  * Returns an Enumerator if no block was given.
02777  */
02778 static VALUE
02779 env_select(VALUE ehash)
02780 {
02781     VALUE result;
02782     char **env;
02783 
02784     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02785     rb_secure(4);
02786     result = rb_hash_new();
02787     env = GET_ENVIRON(environ);
02788     while (*env) {
02789         char *s = strchr(*env, '=');
02790         if (s) {
02791             VALUE k = env_str_new(*env, s-*env);
02792             VALUE v = env_str_new2(s+1);
02793             if (RTEST(rb_yield_values(2, k, v))) {
02794                 rb_hash_aset(result, k, v);
02795             }
02796         }
02797         env++;
02798     }
02799     FREE_ENVIRON(environ);
02800 
02801     return result;
02802 }
02803 
02804 /*
02805  * call-seq:
02806  *   ENV.select! { |name, value| } -> ENV or nil
02807  *   ENV.select!                   -> Enumerator
02808  *
02809  * Equivalent to ENV#keep_if but returns +nil+ if no changes were made.
02810  */
02811 static VALUE
02812 env_select_bang(VALUE ehash)
02813 {
02814     volatile VALUE keys;
02815     long i;
02816     int del = 0;
02817 
02818     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02819     keys = env_keys();  /* rb_secure(4); */
02820     RBASIC(keys)->klass = 0;
02821     for (i=0; i<RARRAY_LEN(keys); i++) {
02822         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02823         if (!NIL_P(val)) {
02824             if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02825                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02826                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02827                 del++;
02828             }
02829         }
02830     }
02831     if (del == 0) return Qnil;
02832     return envtbl;
02833 }
02834 
02835 /*
02836  * call-seq:
02837  *   ENV.keep_if { |name, value| } -> Hash
02838  *   ENV.keep_if                   -> Enumerator
02839  *
02840  * Deletes every environment variable where the block evaluates to +false+.
02841  *
02842  * Returns an enumerator if no block was given.
02843  */
02844 static VALUE
02845 env_keep_if(VALUE ehash)
02846 {
02847     RETURN_SIZED_ENUMERATOR(ehash, 0, 0, rb_env_size);
02848     env_select_bang(ehash);
02849     return envtbl;
02850 }
02851 
02852 /*
02853  * call-seq:
02854  *   ENV.clear
02855  *
02856  * Removes every environment variable.
02857  */
02858 VALUE
02859 rb_env_clear(void)
02860 {
02861     volatile VALUE keys;
02862     long i;
02863 
02864     keys = env_keys();  /* rb_secure(4); */
02865     for (i=0; i<RARRAY_LEN(keys); i++) {
02866         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02867         if (!NIL_P(val)) {
02868             env_delete(Qnil, RARRAY_PTR(keys)[i]);
02869         }
02870     }
02871     return envtbl;
02872 }
02873 
02874 /*
02875  * call-seq:
02876  *   ENV.to_s -> "ENV"
02877  *
02878  * Returns "ENV"
02879  */
02880 static VALUE
02881 env_to_s(void)
02882 {
02883     return rb_usascii_str_new2("ENV");
02884 }
02885 
02886 /*
02887  * call-seq:
02888  *   ENV.inspect -> string
02889  *
02890  * Returns the contents of the environment as a String.
02891  */
02892 static VALUE
02893 env_inspect(void)
02894 {
02895     char **env;
02896     VALUE str, i;
02897 
02898     rb_secure(4);
02899     str = rb_str_buf_new2("{");
02900     env = GET_ENVIRON(environ);
02901     while (*env) {
02902         char *s = strchr(*env, '=');
02903 
02904         if (env != environ) {
02905             rb_str_buf_cat2(str, ", ");
02906         }
02907         if (s) {
02908             rb_str_buf_cat2(str, "\"");
02909             rb_str_buf_cat(str, *env, s-*env);
02910             rb_str_buf_cat2(str, "\"=>");
02911             i = rb_inspect(rb_str_new2(s+1));
02912             rb_str_buf_append(str, i);
02913         }
02914         env++;
02915     }
02916     FREE_ENVIRON(environ);
02917     rb_str_buf_cat2(str, "}");
02918     OBJ_TAINT(str);
02919 
02920     return str;
02921 }
02922 
02923 /*
02924  * call-seq:
02925  *   ENV.to_a -> Array
02926  *
02927  * Converts the environment variables into an array of names and value arrays.
02928  *
02929  *   ENV.to_a # => [["TERM", "xterm-color"], ["SHELL", "/bin/bash"], ...]
02930  *
02931  */
02932 static VALUE
02933 env_to_a(void)
02934 {
02935     char **env;
02936     VALUE ary;
02937 
02938     rb_secure(4);
02939     ary = rb_ary_new();
02940     env = GET_ENVIRON(environ);
02941     while (*env) {
02942         char *s = strchr(*env, '=');
02943         if (s) {
02944             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
02945                                           env_str_new2(s+1)));
02946         }
02947         env++;
02948     }
02949     FREE_ENVIRON(environ);
02950     return ary;
02951 }
02952 
02953 /*
02954  * call-seq:
02955  *   ENV.rehash
02956  *
02957  * Re-hashing the environment variables does nothing.  It is provided for
02958  * compatibility with Hash.
02959  */
02960 static VALUE
02961 env_none(void)
02962 {
02963     return Qnil;
02964 }
02965 
02966 /*
02967  * call-seq:
02968  *   ENV.length
02969  *   ENV.size
02970  *
02971  * Returns the number of environment variables.
02972  */
02973 static VALUE
02974 env_size(void)
02975 {
02976     int i;
02977     char **env;
02978 
02979     rb_secure(4);
02980     env = GET_ENVIRON(environ);
02981     for (i=0; env[i]; i++)
02982         ;
02983     FREE_ENVIRON(environ);
02984     return INT2FIX(i);
02985 }
02986 
02987 /*
02988  * call-seq:
02989  *   ENV.empty? -> true or false
02990  *
02991  * Returns true when there are no environment variables
02992  */
02993 static VALUE
02994 env_empty_p(void)
02995 {
02996     char **env;
02997 
02998     rb_secure(4);
02999     env = GET_ENVIRON(environ);
03000     if (env[0] == 0) {
03001         FREE_ENVIRON(environ);
03002         return Qtrue;
03003     }
03004     FREE_ENVIRON(environ);
03005     return Qfalse;
03006 }
03007 
03008 /*
03009  * call-seq:
03010  *   ENV.key?(name)     -> true or false
03011  *   ENV.include?(name) -> true or false
03012  *   ENV.has_key?(name) -> true or false
03013  *   ENV.member?(name)  -> true or false
03014  *
03015  * Returns +true+ if there is an environment variable with the given +name+.
03016  */
03017 static VALUE
03018 env_has_key(VALUE env, VALUE key)
03019 {
03020     char *s;
03021 
03022     rb_secure(4);
03023     s = StringValuePtr(key);
03024     if (memchr(s, '\0', RSTRING_LEN(key)))
03025         rb_raise(rb_eArgError, "bad environment variable name");
03026     if (getenv(s)) return Qtrue;
03027     return Qfalse;
03028 }
03029 
03030 /*
03031  * call-seq:
03032  *   ENV.assoc(name) -> Array or nil
03033  *
03034  * Returns an Array of the name and value of the environment variable with
03035  * +name+ or +nil+ if the name cannot be found.
03036  */
03037 static VALUE
03038 env_assoc(VALUE env, VALUE key)
03039 {
03040     char *s, *e;
03041 
03042     rb_secure(4);
03043     s = StringValuePtr(key);
03044     if (memchr(s, '\0', RSTRING_LEN(key)))
03045         rb_raise(rb_eArgError, "bad environment variable name");
03046     e = getenv(s);
03047     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
03048     return Qnil;
03049 }
03050 
03051 /*
03052  * call-seq:
03053  *   ENV.value?(value) -> true or false
03054  *   ENV.has_value?(value) -> true or false
03055  *
03056  * Returns +true+ if there is an environment variable with the given +value+.
03057  */
03058 static VALUE
03059 env_has_value(VALUE dmy, VALUE obj)
03060 {
03061     char **env;
03062 
03063     rb_secure(4);
03064     obj = rb_check_string_type(obj);
03065     if (NIL_P(obj)) return Qnil;
03066     env = GET_ENVIRON(environ);
03067     while (*env) {
03068         char *s = strchr(*env, '=');
03069         if (s++) {
03070             long len = strlen(s);
03071             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03072                 FREE_ENVIRON(environ);
03073                 return Qtrue;
03074             }
03075         }
03076         env++;
03077     }
03078     FREE_ENVIRON(environ);
03079     return Qfalse;
03080 }
03081 
03082 /*
03083  * call-seq:
03084  *   ENV.rassoc(value)
03085  *
03086  * Returns an Array of the name and value of the environment variable with
03087  * +value+ or +nil+ if the value cannot be found.
03088  */
03089 static VALUE
03090 env_rassoc(VALUE dmy, VALUE obj)
03091 {
03092     char **env;
03093 
03094     rb_secure(4);
03095     obj = rb_check_string_type(obj);
03096     if (NIL_P(obj)) return Qnil;
03097     env = GET_ENVIRON(environ);
03098     while (*env) {
03099         char *s = strchr(*env, '=');
03100         if (s++) {
03101             long len = strlen(s);
03102             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
03103                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
03104                 FREE_ENVIRON(environ);
03105                 return result;
03106             }
03107         }
03108         env++;
03109     }
03110     FREE_ENVIRON(environ);
03111     return Qnil;
03112 }
03113 
03114 /*
03115  * call-seq:
03116  *   ENV.key(value) -> name
03117  *
03118  * Returns the name of the environment variable with +value+.  If the value is
03119  * not found +nil+ is returned.
03120  */
03121 static VALUE
03122 env_key(VALUE dmy, VALUE value)
03123 {
03124     char **env;
03125     VALUE str;
03126 
03127     rb_secure(4);
03128     StringValue(value);
03129     env = GET_ENVIRON(environ);
03130     while (*env) {
03131         char *s = strchr(*env, '=');
03132         if (s++) {
03133             long len = strlen(s);
03134             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
03135                 str = env_str_new(*env, s-*env-1);
03136                 FREE_ENVIRON(environ);
03137                 return str;
03138             }
03139         }
03140         env++;
03141     }
03142     FREE_ENVIRON(environ);
03143     return Qnil;
03144 }
03145 
03146 /*
03147  * call-seq:
03148  *   ENV.index(value) -> key
03149  *
03150  * Deprecated method that is equivalent to ENV.key
03151  */
03152 static VALUE
03153 env_index(VALUE dmy, VALUE value)
03154 {
03155     rb_warn("ENV.index is deprecated; use ENV.key");
03156     return env_key(dmy, value);
03157 }
03158 
03159 /*
03160  * call-seq:
03161  *   ENV.to_hash -> hash
03162  *   ENV.to_h    -> hash
03163  *
03164  * Creates a hash with a copy of the environment variables.
03165  *
03166  */
03167 static VALUE
03168 env_to_hash(void)
03169 {
03170     char **env;
03171     VALUE hash;
03172 
03173     rb_secure(4);
03174     hash = rb_hash_new();
03175     env = GET_ENVIRON(environ);
03176     while (*env) {
03177         char *s = strchr(*env, '=');
03178         if (s) {
03179             rb_hash_aset(hash, env_str_new(*env, s-*env),
03180                                env_str_new2(s+1));
03181         }
03182         env++;
03183     }
03184     FREE_ENVIRON(environ);
03185     return hash;
03186 }
03187 
03188 /*
03189  * call-seq:
03190  *   ENV.reject { |name, value| } -> Hash
03191  *   ENV.reject                   -> Enumerator
03192  *
03193  * Same as ENV#delete_if, but works on (and returns) a copy of the
03194  * environment.
03195  */
03196 static VALUE
03197 env_reject(void)
03198 {
03199     return rb_hash_delete_if(env_to_hash());
03200 }
03201 
03202 /*
03203  * call-seq:
03204  *   ENV.shift -> Array or nil
03205  *
03206  * Removes an environment variable name-value pair from ENV and returns it as
03207  * an Array.  Returns +nil+ if when the environment is empty.
03208  */
03209 static VALUE
03210 env_shift(void)
03211 {
03212     char **env;
03213 
03214     rb_secure(4);
03215     env = GET_ENVIRON(environ);
03216     if (*env) {
03217         char *s = strchr(*env, '=');
03218         if (s) {
03219             VALUE key = env_str_new(*env, s-*env);
03220             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
03221             env_delete(Qnil, key);
03222             return rb_assoc_new(key, val);
03223         }
03224     }
03225     FREE_ENVIRON(environ);
03226     return Qnil;
03227 }
03228 
03229 /*
03230  * call-seq:
03231  *   ENV.invert -> Hash
03232  *
03233  * Returns a new hash created by using environment variable names as values
03234  * and values as names.
03235  */
03236 static VALUE
03237 env_invert(void)
03238 {
03239     return rb_hash_invert(env_to_hash());
03240 }
03241 
03242 static int
03243 env_replace_i(VALUE key, VALUE val, VALUE keys)
03244 {
03245     env_aset(Qnil, key, val);
03246     if (rb_ary_includes(keys, key)) {
03247         rb_ary_delete(keys, key);
03248     }
03249     return ST_CONTINUE;
03250 }
03251 
03252 /*
03253  * call-seq:
03254  *   ENV.replace(hash) -> env
03255  *
03256  * Replaces the contents of the environment variables with the contents of
03257  * +hash+.
03258  */
03259 static VALUE
03260 env_replace(VALUE env, VALUE hash)
03261 {
03262     volatile VALUE keys;
03263     long i;
03264 
03265     keys = env_keys();  /* rb_secure(4); */
03266     if (env == hash) return env;
03267     hash = to_hash(hash);
03268     rb_hash_foreach(hash, env_replace_i, keys);
03269 
03270     for (i=0; i<RARRAY_LEN(keys); i++) {
03271         env_delete(env, RARRAY_PTR(keys)[i]);
03272     }
03273     return env;
03274 }
03275 
03276 static int
03277 env_update_i(VALUE key, VALUE val)
03278 {
03279     if (rb_block_given_p()) {
03280         val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
03281     }
03282     env_aset(Qnil, key, val);
03283     return ST_CONTINUE;
03284 }
03285 
03286 /*
03287  * call-seq:
03288  *   ENV.update(hash)                                  -> Hash
03289  *   ENV.update(hash) { |name, old_value, new_value| } -> Hash
03290  *
03291  * Adds the contents of +hash+ to the environment variables.  If no block is
03292  * specified entries with duplicate keys are overwritten, otherwise the value
03293  * of each duplicate name is determined by calling the block with the key, its
03294  * value from the environment and its value from the hash.
03295  */
03296 static VALUE
03297 env_update(VALUE env, VALUE hash)
03298 {
03299     rb_secure(4);
03300     if (env == hash) return env;
03301     hash = to_hash(hash);
03302     rb_hash_foreach(hash, env_update_i, 0);
03303     return env;
03304 }
03305 
03306 /*
03307  *  A Hash is a dictionary-like collection of unique keys and their values.
03308  *  Also called associative arrays, they are similar to Arrays, but where an
03309  *  Array uses integers as its index, a Hash allows you to use any object
03310  *  type.
03311  *
03312  *  Hashes enumerate their values in the order that the corresponding keys
03313  *  were inserted.
03314  *
03315  *  A Hash can be easily created by using its implicit form:
03316  *
03317  *    grades = { "Jane Doe" => 10, "Jim Doe" => 6 }
03318  *
03319  *  Hashes allow an alternate syntax form when your keys are always symbols.
03320  *  Instead of
03321  *
03322  *    options = { :font_size => 10, :font_family => "Arial" }
03323  *
03324  *  You could write it as:
03325  *
03326  *    options = { font_size: 10, font_family: "Arial" }
03327  *
03328  *  Each named key is a symbol you can access in hash:
03329  *
03330  *    options[:font_size]  # => 10
03331  *
03332  *  A Hash can also be created through its ::new method:
03333  *
03334  *    grades = Hash.new
03335  *    grades["Dorothy Doe"] = 9
03336  *
03337  *  Hashes have a <em>default value</em> that is returned when accessing
03338  *  keys that do not exist in the hash. If no default is set +nil+ is used.
03339  *  You can set the default value by sending it as an argument to Hash.new:
03340  *
03341  *    grades = Hash.new(0)
03342  *
03343  *  Or by using the #default= method:
03344  *
03345  *    grades = {"Timmy Doe" => 8}
03346  *    grades.default = 0
03347  *
03348  *  Accessing a value in a Hash requires using its key:
03349  *
03350  *    puts grades["Jane Doe"] # => 10
03351  *
03352  *  === Common Uses
03353  *
03354  *  Hashes are an easy way to represent data structures, such as
03355  *
03356  *    books         = {}
03357  *    books[:matz]  = "The Ruby Language"
03358  *    books[:black] = "The Well-Grounded Rubyist"
03359  *
03360  *  Hashes are also commonly used as a way to have named parameters in
03361  *  functions. Note that no brackets are used below. If a hash is the last
03362  *  argument on a method call, no braces are needed, thus creating a really
03363  *  clean interface:
03364  *
03365  *    Person.create(name: "John Doe", age: 27)
03366  *
03367  *    def self.create(params)
03368  *      @name = params[:name]
03369  *      @age  = params[:age]
03370  *    end
03371  *
03372  *  === Hash Keys
03373  *
03374  *  Two objects refer to the same hash key when their <code>hash</code> value
03375  *  is identical and the two objects are <code>eql?</code> to each other.
03376  *
03377  *  A user-defined class may be used as a hash key if the <code>hash</code>
03378  *  and <code>eql?</code> methods are overridden to provide meaningful
03379  *  behavior.  By default, separate instances refer to separate hash keys.
03380  *
03381  *  A typical implementation of <code>hash</code> is based on the
03382  *  object's data while <code>eql?</code> is usually aliased to the overridden
03383  *  <code>==</code> method:
03384  *
03385  *    class Book
03386  *      attr_reader :author, :title
03387  *
03388  *      def initialize(author, title)
03389  *        @author = author
03390  *        @title = title
03391  *      end
03392  *
03393  *      def ==(other)
03394  *        self.class === other and
03395  *          other.author == @author and
03396  *          other.title == @title
03397  *      end
03398  *
03399  *      alias eql? ==
03400  *
03401  *      def hash
03402  *        @author.hash ^ @title.hash # XOR
03403  *      end
03404  *    end
03405  *
03406  *    book1 = Book.new 'matz', 'Ruby in a Nutshell'
03407  *    book2 = Book.new 'matz', 'Ruby in a Nutshell'
03408  *
03409  *    reviews = {}
03410  *
03411  *    reviews[book1] = 'Great reference!'
03412  *    reviews[book2] = 'Nice and compact!'
03413  *
03414  *    reviews.length #=> 1
03415  *
03416  *  See also Object#hash and Object#eql?
03417  */
03418 
03419 void
03420 Init_Hash(void)
03421 {
03422 #undef rb_intern
03423 #define rb_intern(str) rb_intern_const(str)
03424 
03425     id_hash = rb_intern("hash");
03426     id_yield = rb_intern("yield");
03427     id_default = rb_intern("default");
03428 
03429     rb_cHash = rb_define_class("Hash", rb_cObject);
03430 
03431     rb_include_module(rb_cHash, rb_mEnumerable);
03432 
03433     rb_define_alloc_func(rb_cHash, empty_hash_alloc);
03434     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
03435     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
03436     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
03437     rb_define_method(rb_cHash,"initialize_copy", rb_hash_initialize_copy, 1);
03438     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
03439 
03440     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
03441     rb_define_method(rb_cHash,"to_h", rb_hash_to_h, 0);
03442     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
03443     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
03444     rb_define_alias(rb_cHash, "to_s", "inspect");
03445 
03446     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
03447     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
03448     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
03449     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
03450     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
03451     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
03452     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
03453     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
03454     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
03455     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
03456     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
03457     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
03458     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
03459     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
03460     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
03461     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
03462 
03463     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
03464     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
03465     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
03466     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
03467 
03468     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
03469     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
03470     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
03471 
03472     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
03473     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
03474     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
03475     rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
03476     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
03477     rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
03478     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
03479     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
03480     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
03481     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
03482     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
03483     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
03484     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
03485     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
03486     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
03487     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
03488     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
03489 
03490     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
03491     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
03492     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
03493     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
03494     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
03495     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
03496 
03497     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
03498     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
03499 
03500     /* Document-class: ENV
03501      *
03502      * ENV is a hash-like accessor for environment variables.
03503      */
03504 
03505     /*
03506      * Hack to get RDoc to regard ENV as a class:
03507      * envtbl = rb_define_class("ENV", rb_cObject);
03508      */
03509     origenviron = environ;
03510     envtbl = rb_obj_alloc(rb_cObject);
03511     rb_extend_object(envtbl, rb_mEnumerable);
03512 
03513     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
03514     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
03515     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
03516     rb_define_singleton_method(envtbl,"store", env_aset, 2);
03517     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
03518     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
03519     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
03520     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
03521     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
03522     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
03523     rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
03524     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
03525     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
03526     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
03527     rb_define_singleton_method(envtbl,"select", env_select, 0);
03528     rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
03529     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
03530     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
03531     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
03532     rb_define_singleton_method(envtbl,"update", env_update, 1);
03533     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
03534     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
03535     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
03536     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
03537     rb_define_singleton_method(envtbl,"key", env_key, 1);
03538     rb_define_singleton_method(envtbl,"index", env_index, 1);
03539     rb_define_singleton_method(envtbl,"size", env_size, 0);
03540     rb_define_singleton_method(envtbl,"length", env_size, 0);
03541     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
03542     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
03543     rb_define_singleton_method(envtbl,"values", env_values, 0);
03544     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
03545     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
03546     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
03547     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
03548     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
03549     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
03550     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
03551     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
03552     rb_define_singleton_method(envtbl,"to_h", env_to_hash, 0);
03553     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
03554     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
03555 
03556     /*
03557      * ENV is a Hash-like accessor for environment variables.
03558      *
03559      * See ENV (the class) for more details.
03560      */
03561     rb_define_global_const("ENV", envtbl);
03562 }
03563