hash.c

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

Generated on Wed Aug 10 09:17:07 2011 for Ruby by  doxygen 1.4.7