diff options
author | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-13 09:21:18 +0000 |
---|---|---|
committer | matz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2002-08-13 09:21:18 +0000 |
commit | cf5d04f663e9e7a61da4dda66e78097aefe66919 (patch) | |
tree | 431e5afae10458ab9e139683d74724bd713b0ed8 /hash.c | |
parent | 510c93caacad0911261f3adeed73b43fc5fca57f (diff) |
* hash.c (rb_hash_replace): should copy ifnone.
* hash.c (rb_hash_dup): should preserve HASH_PROC_DEFAULT and
HASH_DELETED flags.
* hash.c (rb_hash_shift): shift from empty hash should not return
its default proc.
* hash.c (rb_hash_default_proc): new method. [new]
* array.c (rb_ary_aref): no need for Bignum check.
* array.c (rb_ary_aset): explicit Bignum check removd.
* numeric.c (fix_aref): normalize bignum before bit-op.
* bignum.c (rb_big_rand): max may be Bignum zero.
* bignum.c (rb_cstr_to_inum): should normalize bignums, to avoid
returning fixable bignum value.
* bignum.c (rb_uint2big): there should be no zero sized bignum.
* ext/extmk.rb.in: extmake() that works properly for both tkutil
(tk/tkutil.so) and digest/sha1.
* hash.c (rb_hash_equal): should check HASH_PROC_DEFAULT too.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2706 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 47 |
1 files changed, 44 insertions, 3 deletions
@@ -260,6 +260,21 @@ rb_hash_clone(hash) } static VALUE +rb_hash_dup(hash) + VALUE hash; +{ + VALUE dup = rb_obj_dup(hash); + + if (FL_TEST(hash, HASH_PROC_DEFAULT)) { + FL_SET(dup, HASH_PROC_DEFAULT); + } + if (FL_TEST(hash, HASH_DELETED)) { + FL_SET(dup, HASH_DELETED); + } + return dup; +} + +static VALUE to_hash(hash) VALUE hash; { @@ -353,6 +368,18 @@ rb_hash_set_default(hash, ifnone) return ifnone; } +static VALUE +rb_hash_default_proc(hash) + VALUE hash; +{ + VALUE key; + + if (FL_TEST(hash, HASH_PROC_DEFAULT)) { + return RHASH(hash)->ifnone; + } + return Qnil; +} + static int index_i(key, value, args) VALUE key, value; @@ -448,8 +475,15 @@ rb_hash_shift(hash) var.stop = 0; st_foreach(RHASH(hash)->tbl, shift_i, &var); - if (var.stop == 0) return RHASH(hash)->ifnone; - return rb_assoc_new(var.key, var.val); + if (var.stop) { + return rb_assoc_new(var.key, var.val); + } + else if (FL_TEST(hash, HASH_PROC_DEFAULT)) { + return rb_funcall(RHASH(hash)->ifnone, id_yield, 2, hash, Qnil); + } + else { + return RHASH(hash)->ifnone; + } } static int @@ -573,6 +607,10 @@ rb_hash_replace(hash, hash2) hash2 = to_hash(hash2); rb_hash_clear(hash); st_foreach(RHASH(hash2)->tbl, replace_i, hash); + RHASH(hash)->ifnone = RHASH(hash2)->ifnone; + if (FL_TEST(hash2, HASH_PROC_DEFAULT)) { + FL_SET(hash, HASH_PROC_DEFAULT); + } return hash; } @@ -854,7 +892,8 @@ rb_hash_equal(hash1, hash2) if (TYPE(hash2) != T_HASH) return Qfalse; if (RHASH(hash1)->tbl->num_entries != RHASH(hash2)->tbl->num_entries) return Qfalse; - if (!rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone)) + if (!(rb_equal(RHASH(hash1)->ifnone, RHASH(hash2)->ifnone) && + FL_TEST(hash1, HASH_PROC_DEFAULT) == FL_TEST(hash2, HASH_PROC_DEFAULT))) return Qfalse; data.tbl = RHASH(hash2)->tbl; @@ -1576,6 +1615,7 @@ Init_Hash() rb_define_method(rb_cHash,"initialize", rb_hash_initialize, -1); rb_define_method(rb_cHash,"clone", rb_hash_clone, 0); + rb_define_method(rb_cHash,"dup", rb_hash_dup, 0); rb_define_method(rb_cHash,"rehash", rb_hash_rehash, 0); rb_define_method(rb_cHash,"to_hash", rb_hash_to_hash, 0); @@ -1590,6 +1630,7 @@ Init_Hash() rb_define_method(rb_cHash,"store", rb_hash_aset, 2); rb_define_method(rb_cHash,"default", rb_hash_default, -1); rb_define_method(rb_cHash,"default=", rb_hash_set_default, 1); + rb_define_method(rb_cHash,"default_proc", rb_hash_default_proc, 0); rb_define_method(rb_cHash,"index", rb_hash_index, 1); rb_define_method(rb_cHash,"indexes", rb_hash_indexes, -1); rb_define_method(rb_cHash,"indices", rb_hash_indexes, -1); |