From 89697dc491be7f43cb240ddfddaa9f1503b9fc97 Mon Sep 17 00:00:00 2001 From: matz Date: Tue, 13 Aug 2002 09:21:18 +0000 Subject: * 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: http://svn.ruby-lang.org/repos/ruby/trunk@2706 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- hash.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) (limited to 'hash.c') diff --git a/hash.c b/hash.c index 98bf3427f..dc7483b77 100644 --- a/hash.c +++ b/hash.c @@ -259,6 +259,21 @@ rb_hash_clone(hash) return clone; } +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); -- cgit