• Main Page
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

hash.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   hash.c -
00004 
00005   $Author: marcandre $
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             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     if (strchr(name, '=')) {
02139         errno = EINVAL;
02140         rb_sys_fail("ruby_setenv");
02141     }
02142     if (value) {
02143         len = strlen(name) + 1 + strlen(value) + 1;
02144         buf = ALLOCA_N(char, len);
02145         snprintf(buf, len, "%s=%s", name, value);
02146         putenv(buf);
02147 
02148         /* putenv() doesn't handle empty value */
02149         if (!*value)
02150             SetEnvironmentVariable(name,value);
02151     }
02152     else {
02153         len = strlen(name) + 1 + 1;
02154         buf = ALLOCA_N(char, len);
02155         snprintf(buf, len, "%s=", name);
02156         putenv(buf);
02157         SetEnvironmentVariable(name, 0);
02158     }
02159 #elif defined(HAVE_SETENV) && defined(HAVE_UNSETENV)
02160 #undef setenv
02161 #undef unsetenv
02162     if (value) {
02163         if (setenv(name, value, 1))
02164             rb_sys_fail("setenv");
02165     } else {
02166 #ifdef VOID_UNSETENV
02167         unsetenv(name);
02168 #else
02169         if (unsetenv(name))
02170             rb_sys_fail("unsetenv");
02171 #endif
02172     }
02173 #elif defined __sun__
02174     size_t len;
02175     char **env_ptr, *str;
02176     if (strchr(name, '=')) {
02177         errno = EINVAL;
02178         rb_sys_fail("ruby_setenv");
02179     }
02180     len = strlen(name);
02181     for (env_ptr = GET_ENVIRON(environ); (str = *env_ptr) != 0; ++env_ptr) {
02182         if (!strncmp(str, name, len) && str[len] == '=') {
02183             if (!in_origenv(str)) free(str);
02184             while ((env_ptr[0] = env_ptr[1]) != 0) env_ptr++;
02185             break;
02186         }
02187     }
02188     if (value) {
02189         str = malloc(len += strlen(value) + 2);
02190         snprintf(str, len, "%s=%s", name, value);
02191         if (putenv(str))
02192             rb_sys_fail("putenv");
02193     }
02194 #else  /* WIN32 */
02195     size_t len;
02196     int i;
02197     if (strchr(name, '=')) {
02198         errno = EINVAL;
02199         rb_sys_fail("ruby_setenv");
02200     }
02201     i=envix(name);                      /* where does it go? */
02202 
02203     if (environ == origenviron) {       /* need we copy environment? */
02204         int j;
02205         int max;
02206         char **tmpenv;
02207 
02208         for (max = i; environ[max]; max++) ;
02209         tmpenv = ALLOC_N(char*, max+2);
02210         for (j=0; j<max; j++)           /* copy environment */
02211             tmpenv[j] = ruby_strdup(environ[j]);
02212         tmpenv[max] = 0;
02213         environ = tmpenv;               /* tell exec where it is now */
02214     }
02215     if (environ[i]) {
02216         char **envp = origenviron;
02217         while (*envp && *envp != environ[i]) envp++;
02218         if (!*envp)
02219             xfree(environ[i]);
02220         if (!value) {
02221             while (environ[i]) {
02222                 environ[i] = environ[i+1];
02223                 i++;
02224             }
02225             return;
02226         }
02227     }
02228     else {                      /* does not exist yet */
02229         if (!value) return;
02230         REALLOC_N(environ, char*, i+2); /* just expand it a bit */
02231         environ[i+1] = 0;       /* make sure it's null terminated */
02232     }
02233     len = strlen(name) + strlen(value) + 2;
02234     environ[i] = ALLOC_N(char, len);
02235     snprintf(environ[i],len,"%s=%s",name,value); /* all that work just for this */
02236 #endif /* WIN32 */
02237 }
02238 
02239 void
02240 ruby_unsetenv(const char *name)
02241 {
02242     ruby_setenv(name, 0);
02243 }
02244 
02245 static VALUE
02246 env_aset(VALUE obj, VALUE nm, VALUE val)
02247 {
02248     char *name, *value;
02249 
02250     if (rb_safe_level() >= 4) {
02251         rb_raise(rb_eSecurityError, "can't change environment variable");
02252     }
02253 
02254     if (NIL_P(val)) {
02255         env_delete(obj, nm);
02256         return Qnil;
02257     }
02258     StringValue(nm);
02259     StringValue(val);
02260     name = RSTRING_PTR(nm);
02261     value = RSTRING_PTR(val);
02262     if (memchr(name, '\0', RSTRING_LEN(nm)))
02263         rb_raise(rb_eArgError, "bad environment variable name");
02264     if (memchr(value, '\0', RSTRING_LEN(val)))
02265         rb_raise(rb_eArgError, "bad environment variable value");
02266 
02267     ruby_setenv(name, value);
02268     if (ENVMATCH(name, PATH_ENV)) {
02269         if (OBJ_TAINTED(val)) {
02270             /* already tainted, no check */
02271             path_tainted = 1;
02272             return val;
02273         }
02274         else {
02275             path_tainted_p(value);
02276         }
02277     }
02278     return val;
02279 }
02280 
02281 static VALUE
02282 env_keys(void)
02283 {
02284     char **env;
02285     VALUE ary;
02286 
02287     rb_secure(4);
02288     ary = rb_ary_new();
02289     env = GET_ENVIRON(environ);
02290     while (*env) {
02291         char *s = strchr(*env, '=');
02292         if (s) {
02293             rb_ary_push(ary, env_str_new(*env, s-*env));
02294         }
02295         env++;
02296     }
02297     FREE_ENVIRON(environ);
02298     return ary;
02299 }
02300 
02301 static VALUE
02302 env_each_key(VALUE ehash)
02303 {
02304     VALUE keys;
02305     long i;
02306 
02307     RETURN_ENUMERATOR(ehash, 0, 0);
02308     keys = env_keys();  /* rb_secure(4); */
02309     for (i=0; i<RARRAY_LEN(keys); i++) {
02310         rb_yield(RARRAY_PTR(keys)[i]);
02311     }
02312     return ehash;
02313 }
02314 
02315 static VALUE
02316 env_values(void)
02317 {
02318     VALUE ary;
02319     char **env;
02320 
02321     rb_secure(4);
02322     ary = rb_ary_new();
02323     env = GET_ENVIRON(environ);
02324     while (*env) {
02325         char *s = strchr(*env, '=');
02326         if (s) {
02327             rb_ary_push(ary, env_str_new2(s+1));
02328         }
02329         env++;
02330     }
02331     FREE_ENVIRON(environ);
02332     return ary;
02333 }
02334 
02335 static VALUE
02336 env_each_value(VALUE ehash)
02337 {
02338     VALUE values;
02339     long i;
02340 
02341     RETURN_ENUMERATOR(ehash, 0, 0);
02342     values = env_values();      /* rb_secure(4); */
02343     for (i=0; i<RARRAY_LEN(values); i++) {
02344         rb_yield(RARRAY_PTR(values)[i]);
02345     }
02346     return ehash;
02347 }
02348 
02349 static VALUE
02350 env_each_pair(VALUE ehash)
02351 {
02352     char **env;
02353     VALUE ary;
02354     long i;
02355 
02356     RETURN_ENUMERATOR(ehash, 0, 0);
02357 
02358     rb_secure(4);
02359     ary = rb_ary_new();
02360     env = GET_ENVIRON(environ);
02361     while (*env) {
02362         char *s = strchr(*env, '=');
02363         if (s) {
02364             rb_ary_push(ary, env_str_new(*env, s-*env));
02365             rb_ary_push(ary, env_str_new2(s+1));
02366         }
02367         env++;
02368     }
02369     FREE_ENVIRON(environ);
02370 
02371     for (i=0; i<RARRAY_LEN(ary); i+=2) {
02372         rb_yield(rb_assoc_new(RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]));
02373     }
02374     return ehash;
02375 }
02376 
02377 static VALUE
02378 env_reject_bang(VALUE ehash)
02379 {
02380     volatile VALUE keys;
02381     long i;
02382     int del = 0;
02383 
02384     RETURN_ENUMERATOR(ehash, 0, 0);
02385     keys = env_keys();  /* rb_secure(4); */
02386     for (i=0; i<RARRAY_LEN(keys); i++) {
02387         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02388         if (!NIL_P(val)) {
02389             if (RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02390                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02391                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02392                 del++;
02393             }
02394         }
02395     }
02396     if (del == 0) return Qnil;
02397     return envtbl;
02398 }
02399 
02400 static VALUE
02401 env_delete_if(VALUE ehash)
02402 {
02403     RETURN_ENUMERATOR(ehash, 0, 0);
02404     env_reject_bang(ehash);
02405     return envtbl;
02406 }
02407 
02408 static VALUE
02409 env_values_at(int argc, VALUE *argv)
02410 {
02411     VALUE result;
02412     long i;
02413 
02414     rb_secure(4);
02415     result = rb_ary_new();
02416     for (i=0; i<argc; i++) {
02417         rb_ary_push(result, rb_f_getenv(Qnil, argv[i]));
02418     }
02419     return result;
02420 }
02421 
02422 static VALUE
02423 env_select(VALUE ehash)
02424 {
02425     VALUE result;
02426     char **env;
02427 
02428     RETURN_ENUMERATOR(ehash, 0, 0);
02429     rb_secure(4);
02430     result = rb_hash_new();
02431     env = GET_ENVIRON(environ);
02432     while (*env) {
02433         char *s = strchr(*env, '=');
02434         if (s) {
02435             VALUE k = env_str_new(*env, s-*env);
02436             VALUE v = env_str_new2(s+1);
02437             if (RTEST(rb_yield_values(2, k, v))) {
02438                 rb_hash_aset(result, k, v);
02439             }
02440         }
02441         env++;
02442     }
02443     FREE_ENVIRON(environ);
02444 
02445     return result;
02446 }
02447 
02448 static VALUE
02449 env_select_bang(VALUE ehash)
02450 {
02451     volatile VALUE keys;
02452     long i;
02453     int del = 0;
02454 
02455     RETURN_ENUMERATOR(ehash, 0, 0);
02456     keys = env_keys();  /* rb_secure(4); */
02457     for (i=0; i<RARRAY_LEN(keys); i++) {
02458         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02459         if (!NIL_P(val)) {
02460             if (!RTEST(rb_yield_values(2, RARRAY_PTR(keys)[i], val))) {
02461                 FL_UNSET(RARRAY_PTR(keys)[i], FL_TAINT);
02462                 env_delete(Qnil, RARRAY_PTR(keys)[i]);
02463                 del++;
02464             }
02465         }
02466     }
02467     if (del == 0) return Qnil;
02468     return envtbl;
02469 }
02470 
02471 static VALUE
02472 env_keep_if(VALUE ehash)
02473 {
02474     RETURN_ENUMERATOR(ehash, 0, 0);
02475     env_select_bang(ehash);
02476     return envtbl;
02477 }
02478 
02479 VALUE
02480 rb_env_clear(void)
02481 {
02482     volatile VALUE keys;
02483     long i;
02484 
02485     keys = env_keys();  /* rb_secure(4); */
02486     for (i=0; i<RARRAY_LEN(keys); i++) {
02487         VALUE val = rb_f_getenv(Qnil, RARRAY_PTR(keys)[i]);
02488         if (!NIL_P(val)) {
02489             env_delete(Qnil, RARRAY_PTR(keys)[i]);
02490         }
02491     }
02492     return envtbl;
02493 }
02494 
02495 static VALUE
02496 env_to_s(void)
02497 {
02498     return rb_usascii_str_new2("ENV");
02499 }
02500 
02501 static VALUE
02502 env_inspect(void)
02503 {
02504     char **env;
02505     VALUE str, i;
02506 
02507     rb_secure(4);
02508     str = rb_str_buf_new2("{");
02509     env = GET_ENVIRON(environ);
02510     while (*env) {
02511         char *s = strchr(*env, '=');
02512 
02513         if (env != environ) {
02514             rb_str_buf_cat2(str, ", ");
02515         }
02516         if (s) {
02517             rb_str_buf_cat2(str, "\"");
02518             rb_str_buf_cat(str, *env, s-*env);
02519             rb_str_buf_cat2(str, "\"=>");
02520             i = rb_inspect(rb_str_new2(s+1));
02521             rb_str_buf_append(str, i);
02522         }
02523         env++;
02524     }
02525     FREE_ENVIRON(environ);
02526     rb_str_buf_cat2(str, "}");
02527     OBJ_TAINT(str);
02528 
02529     return str;
02530 }
02531 
02532 static VALUE
02533 env_to_a(void)
02534 {
02535     char **env;
02536     VALUE ary;
02537 
02538     rb_secure(4);
02539     ary = rb_ary_new();
02540     env = GET_ENVIRON(environ);
02541     while (*env) {
02542         char *s = strchr(*env, '=');
02543         if (s) {
02544             rb_ary_push(ary, rb_assoc_new(env_str_new(*env, s-*env),
02545                                           env_str_new2(s+1)));
02546         }
02547         env++;
02548     }
02549     FREE_ENVIRON(environ);
02550     return ary;
02551 }
02552 
02553 static VALUE
02554 env_none(void)
02555 {
02556     return Qnil;
02557 }
02558 
02559 static VALUE
02560 env_size(void)
02561 {
02562     int i;
02563     char **env;
02564 
02565     rb_secure(4);
02566     env = GET_ENVIRON(environ);
02567     for(i=0; env[i]; i++)
02568         ;
02569     FREE_ENVIRON(environ);
02570     return INT2FIX(i);
02571 }
02572 
02573 static VALUE
02574 env_empty_p(void)
02575 {
02576     char **env;
02577 
02578     rb_secure(4);
02579     env = GET_ENVIRON(environ);
02580     if (env[0] == 0) {
02581         FREE_ENVIRON(environ);
02582         return Qtrue;
02583     }
02584     FREE_ENVIRON(environ);
02585     return Qfalse;
02586 }
02587 
02588 static VALUE
02589 env_has_key(VALUE env, VALUE key)
02590 {
02591     char *s;
02592 
02593     rb_secure(4);
02594     s = StringValuePtr(key);
02595     if (memchr(s, '\0', RSTRING_LEN(key)))
02596         rb_raise(rb_eArgError, "bad environment variable name");
02597     if (getenv(s)) return Qtrue;
02598     return Qfalse;
02599 }
02600 
02601 static VALUE
02602 env_assoc(VALUE env, VALUE key)
02603 {
02604     char *s, *e;
02605 
02606     rb_secure(4);
02607     s = StringValuePtr(key);
02608     if (memchr(s, '\0', RSTRING_LEN(key)))
02609         rb_raise(rb_eArgError, "bad environment variable name");
02610     e = getenv(s);
02611     if (e) return rb_assoc_new(key, rb_tainted_str_new2(e));
02612     return Qnil;
02613 }
02614 
02615 static VALUE
02616 env_has_value(VALUE dmy, VALUE obj)
02617 {
02618     char **env;
02619 
02620     rb_secure(4);
02621     obj = rb_check_string_type(obj);
02622     if (NIL_P(obj)) return Qnil;
02623     env = GET_ENVIRON(environ);
02624     while (*env) {
02625         char *s = strchr(*env, '=');
02626         if (s++) {
02627             long len = strlen(s);
02628             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
02629                 FREE_ENVIRON(environ);
02630                 return Qtrue;
02631             }
02632         }
02633         env++;
02634     }
02635     FREE_ENVIRON(environ);
02636     return Qfalse;
02637 }
02638 
02639 static VALUE
02640 env_rassoc(VALUE dmy, VALUE obj)
02641 {
02642     char **env;
02643 
02644     rb_secure(4);
02645     obj = rb_check_string_type(obj);
02646     if (NIL_P(obj)) return Qnil;
02647     env = GET_ENVIRON(environ);
02648     while (*env) {
02649         char *s = strchr(*env, '=');
02650         if (s++) {
02651             long len = strlen(s);
02652             if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) {
02653                 VALUE result = rb_assoc_new(rb_tainted_str_new(*env, s-*env-1), obj);
02654                 FREE_ENVIRON(environ);
02655                 return result;
02656             }
02657         }
02658         env++;
02659     }
02660     FREE_ENVIRON(environ);
02661     return Qnil;
02662 }
02663 
02664 static VALUE
02665 env_key(VALUE dmy, VALUE value)
02666 {
02667     char **env;
02668     VALUE str;
02669 
02670     rb_secure(4);
02671     StringValue(value);
02672     env = GET_ENVIRON(environ);
02673     while (*env) {
02674         char *s = strchr(*env, '=');
02675         if (s++) {
02676             long len = strlen(s);
02677             if (RSTRING_LEN(value) == len && strncmp(s, RSTRING_PTR(value), len) == 0) {
02678                 str = env_str_new(*env, s-*env-1);
02679                 FREE_ENVIRON(environ);
02680                 return str;
02681             }
02682         }
02683         env++;
02684     }
02685     FREE_ENVIRON(environ);
02686     return Qnil;
02687 }
02688 
02689 static VALUE
02690 env_index(VALUE dmy, VALUE value)
02691 {
02692     rb_warn("ENV.index is deprecated; use ENV.key");
02693     return env_key(dmy, value);
02694 }
02695 
02696 static VALUE
02697 env_to_hash(void)
02698 {
02699     char **env;
02700     VALUE hash;
02701 
02702     rb_secure(4);
02703     hash = rb_hash_new();
02704     env = GET_ENVIRON(environ);
02705     while (*env) {
02706         char *s = strchr(*env, '=');
02707         if (s) {
02708             rb_hash_aset(hash, env_str_new(*env, s-*env),
02709                                env_str_new2(s+1));
02710         }
02711         env++;
02712     }
02713     FREE_ENVIRON(environ);
02714     return hash;
02715 }
02716 
02717 static VALUE
02718 env_reject(void)
02719 {
02720     return rb_hash_delete_if(env_to_hash());
02721 }
02722 
02723 static VALUE
02724 env_shift(void)
02725 {
02726     char **env;
02727 
02728     rb_secure(4);
02729     env = GET_ENVIRON(environ);
02730     if (*env) {
02731         char *s = strchr(*env, '=');
02732         if (s) {
02733             VALUE key = env_str_new(*env, s-*env);
02734             VALUE val = env_str_new2(getenv(RSTRING_PTR(key)));
02735             env_delete(Qnil, key);
02736             return rb_assoc_new(key, val);
02737         }
02738     }
02739     FREE_ENVIRON(environ);
02740     return Qnil;
02741 }
02742 
02743 static VALUE
02744 env_invert(void)
02745 {
02746     return rb_hash_invert(env_to_hash());
02747 }
02748 
02749 static int
02750 env_replace_i(VALUE key, VALUE val, VALUE keys)
02751 {
02752     if (key != Qundef) {
02753         env_aset(Qnil, key, val);
02754         if (rb_ary_includes(keys, key)) {
02755             rb_ary_delete(keys, key);
02756         }
02757     }
02758     return ST_CONTINUE;
02759 }
02760 
02761 static VALUE
02762 env_replace(VALUE env, VALUE hash)
02763 {
02764     volatile VALUE keys;
02765     long i;
02766 
02767     keys = env_keys();  /* rb_secure(4); */
02768     if (env == hash) return env;
02769     hash = to_hash(hash);
02770     rb_hash_foreach(hash, env_replace_i, keys);
02771 
02772     for (i=0; i<RARRAY_LEN(keys); i++) {
02773         env_delete(env, RARRAY_PTR(keys)[i]);
02774     }
02775     return env;
02776 }
02777 
02778 static int
02779 env_update_i(VALUE key, VALUE val)
02780 {
02781     if (key != Qundef) {
02782         if (rb_block_given_p()) {
02783             val = rb_yield_values(3, key, rb_f_getenv(Qnil, key), val);
02784         }
02785         env_aset(Qnil, key, val);
02786     }
02787     return ST_CONTINUE;
02788 }
02789 
02790 static VALUE
02791 env_update(VALUE env, VALUE hash)
02792 {
02793     rb_secure(4);
02794     if (env == hash) return env;
02795     hash = to_hash(hash);
02796     rb_hash_foreach(hash, env_update_i, 0);
02797     return env;
02798 }
02799 
02800 /*
02801  *  A <code>Hash</code> is a collection of key-value pairs. It is
02802  *  similar to an <code>Array</code>, except that indexing is done via
02803  *  arbitrary keys of any object type, not an integer index. Hashes enumerate
02804  *  their values in the order that the corresponding keys were inserted.
02805  *
02806  *  Hashes have a <em>default value</em> that is returned when accessing
02807  *  keys that do not exist in the hash. By default, that value is
02808  *  <code>nil</code>.
02809  *
02810  */
02811 
02812 void
02813 Init_Hash(void)
02814 {
02815 #undef rb_intern
02816 #define rb_intern(str) rb_intern_const(str)
02817 
02818     id_hash = rb_intern("hash");
02819     id_yield = rb_intern("yield");
02820     id_default = rb_intern("default");
02821 
02822     rb_cHash = rb_define_class("Hash", rb_cObject);
02823 
02824     rb_include_module(rb_cHash, rb_mEnumerable);
02825 
02826     rb_define_alloc_func(rb_cHash, hash_alloc);
02827     rb_define_singleton_method(rb_cHash, "[]", rb_hash_s_create, -1);
02828     rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
02829     rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1);
02830     rb_define_method(rb_cHash,"initialize_copy", rb_hash_replace, 1);
02831     rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0);
02832 
02833     rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0);
02834     rb_define_method(rb_cHash,"to_a", rb_hash_to_a, 0);
02835     rb_define_method(rb_cHash,"inspect", rb_hash_inspect, 0);
02836     rb_define_alias(rb_cHash, "to_s", "inspect");
02837 
02838     rb_define_method(rb_cHash,"==", rb_hash_equal, 1);
02839     rb_define_method(rb_cHash,"[]", rb_hash_aref, 1);
02840     rb_define_method(rb_cHash,"hash", rb_hash_hash, 0);
02841     rb_define_method(rb_cHash,"eql?", rb_hash_eql, 1);
02842     rb_define_method(rb_cHash,"fetch", rb_hash_fetch_m, -1);
02843     rb_define_method(rb_cHash,"[]=", rb_hash_aset, 2);
02844     rb_define_method(rb_cHash,"store", rb_hash_aset, 2);
02845     rb_define_method(rb_cHash,"default", rb_hash_default, -1);
02846     rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1);
02847     rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0);
02848     rb_define_method(rb_cHash,"default_proc=", rb_hash_set_default_proc, 1);
02849     rb_define_method(rb_cHash,"key", rb_hash_key, 1);
02850     rb_define_method(rb_cHash,"index", rb_hash_index, 1);
02851     rb_define_method(rb_cHash,"size", rb_hash_size, 0);
02852     rb_define_method(rb_cHash,"length", rb_hash_size, 0);
02853     rb_define_method(rb_cHash,"empty?", rb_hash_empty_p, 0);
02854 
02855     rb_define_method(rb_cHash,"each_value", rb_hash_each_value, 0);
02856     rb_define_method(rb_cHash,"each_key", rb_hash_each_key, 0);
02857     rb_define_method(rb_cHash,"each_pair", rb_hash_each_pair, 0);
02858     rb_define_method(rb_cHash,"each", rb_hash_each_pair, 0);
02859 
02860     rb_define_method(rb_cHash,"keys", rb_hash_keys, 0);
02861     rb_define_method(rb_cHash,"values", rb_hash_values, 0);
02862     rb_define_method(rb_cHash,"values_at", rb_hash_values_at, -1);
02863 
02864     rb_define_method(rb_cHash,"shift", rb_hash_shift, 0);
02865     rb_define_method(rb_cHash,"delete", rb_hash_delete, 1);
02866     rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0);
02867     rb_define_method(rb_cHash,"keep_if", rb_hash_keep_if, 0);
02868     rb_define_method(rb_cHash,"select", rb_hash_select, 0);
02869     rb_define_method(rb_cHash,"select!", rb_hash_select_bang, 0);
02870     rb_define_method(rb_cHash,"reject", rb_hash_reject, 0);
02871     rb_define_method(rb_cHash,"reject!", rb_hash_reject_bang, 0);
02872     rb_define_method(rb_cHash,"clear", rb_hash_clear, 0);
02873     rb_define_method(rb_cHash,"invert", rb_hash_invert, 0);
02874     rb_define_method(rb_cHash,"update", rb_hash_update, 1);
02875     rb_define_method(rb_cHash,"replace", rb_hash_replace, 1);
02876     rb_define_method(rb_cHash,"merge!", rb_hash_update, 1);
02877     rb_define_method(rb_cHash,"merge", rb_hash_merge, 1);
02878     rb_define_method(rb_cHash, "assoc", rb_hash_assoc, 1);
02879     rb_define_method(rb_cHash, "rassoc", rb_hash_rassoc, 1);
02880     rb_define_method(rb_cHash, "flatten", rb_hash_flatten, -1);
02881 
02882     rb_define_method(rb_cHash,"include?", rb_hash_has_key, 1);
02883     rb_define_method(rb_cHash,"member?", rb_hash_has_key, 1);
02884     rb_define_method(rb_cHash,"has_key?", rb_hash_has_key, 1);
02885     rb_define_method(rb_cHash,"has_value?", rb_hash_has_value, 1);
02886     rb_define_method(rb_cHash,"key?", rb_hash_has_key, 1);
02887     rb_define_method(rb_cHash,"value?", rb_hash_has_value, 1);
02888 
02889     rb_define_method(rb_cHash,"compare_by_identity", rb_hash_compare_by_id, 0);
02890     rb_define_method(rb_cHash,"compare_by_identity?", rb_hash_compare_by_id_p, 0);
02891 
02892     origenviron = environ;
02893     envtbl = rb_obj_alloc(rb_cObject);
02894     rb_extend_object(envtbl, rb_mEnumerable);
02895 
02896     rb_define_singleton_method(envtbl,"[]", rb_f_getenv, 1);
02897     rb_define_singleton_method(envtbl,"fetch", env_fetch, -1);
02898     rb_define_singleton_method(envtbl,"[]=", env_aset, 2);
02899     rb_define_singleton_method(envtbl,"store", env_aset, 2);
02900     rb_define_singleton_method(envtbl,"each", env_each_pair, 0);
02901     rb_define_singleton_method(envtbl,"each_pair", env_each_pair, 0);
02902     rb_define_singleton_method(envtbl,"each_key", env_each_key, 0);
02903     rb_define_singleton_method(envtbl,"each_value", env_each_value, 0);
02904     rb_define_singleton_method(envtbl,"delete", env_delete_m, 1);
02905     rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0);
02906     rb_define_singleton_method(envtbl,"keep_if", env_keep_if, 0);
02907     rb_define_singleton_method(envtbl,"clear", rb_env_clear, 0);
02908     rb_define_singleton_method(envtbl,"reject", env_reject, 0);
02909     rb_define_singleton_method(envtbl,"reject!", env_reject_bang, 0);
02910     rb_define_singleton_method(envtbl,"select", env_select, 0);
02911     rb_define_singleton_method(envtbl,"select!", env_select_bang, 0);
02912     rb_define_singleton_method(envtbl,"shift", env_shift, 0);
02913     rb_define_singleton_method(envtbl,"invert", env_invert, 0);
02914     rb_define_singleton_method(envtbl,"replace", env_replace, 1);
02915     rb_define_singleton_method(envtbl,"update", env_update, 1);
02916     rb_define_singleton_method(envtbl,"inspect", env_inspect, 0);
02917     rb_define_singleton_method(envtbl,"rehash", env_none, 0);
02918     rb_define_singleton_method(envtbl,"to_a", env_to_a, 0);
02919     rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
02920     rb_define_singleton_method(envtbl,"key", env_key, 1);
02921     rb_define_singleton_method(envtbl,"index", env_index, 1);
02922     rb_define_singleton_method(envtbl,"size", env_size, 0);
02923     rb_define_singleton_method(envtbl,"length", env_size, 0);
02924     rb_define_singleton_method(envtbl,"empty?", env_empty_p, 0);
02925     rb_define_singleton_method(envtbl,"keys", env_keys, 0);
02926     rb_define_singleton_method(envtbl,"values", env_values, 0);
02927     rb_define_singleton_method(envtbl,"values_at", env_values_at, -1);
02928     rb_define_singleton_method(envtbl,"include?", env_has_key, 1);
02929     rb_define_singleton_method(envtbl,"member?", env_has_key, 1);
02930     rb_define_singleton_method(envtbl,"has_key?", env_has_key, 1);
02931     rb_define_singleton_method(envtbl,"has_value?", env_has_value, 1);
02932     rb_define_singleton_method(envtbl,"key?", env_has_key, 1);
02933     rb_define_singleton_method(envtbl,"value?", env_has_value, 1);
02934     rb_define_singleton_method(envtbl,"to_hash", env_to_hash, 0);
02935     rb_define_singleton_method(envtbl,"assoc", env_assoc, 1);
02936     rb_define_singleton_method(envtbl,"rassoc", env_rassoc, 1);
02937 
02938     rb_define_global_const("ENV", envtbl);
02939 }
02940 

Generated on Wed Sep 8 2010 09:55:46 for Ruby by  doxygen 1.7.1