diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-31 05:23:01 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-03-31 05:23:01 +0000 |
commit | 160d02d830d93316a8b4afd54138c1a8bfb8a6b3 (patch) | |
tree | 10f355909c45a2d9bf76f3918964533519ce9fc7 /hash.c | |
parent | 15ca66efb0292388e2c8b6772bf0549a7c396eb9 (diff) | |
download | ruby-160d02d830d93316a8b4afd54138c1a8bfb8a6b3.tar.gz |
* hash.c (hash_default_value): extract from rb_hash_aref(), to be
shared with rb_hash_shift(), so that overriding Hash#default
will be respected.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35197 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 29 |
1 files changed, 16 insertions, 13 deletions
@@ -480,6 +480,20 @@ rb_hash_rehash(VALUE hash) return hash; } +static VALUE +hash_default_value(VALUE hash, VALUE key) +{ + if (rb_method_basic_definition_p(CLASS_OF(hash), id_default)) { + VALUE ifnone = RHASH_IFNONE(hash); + if (!FL_TEST(hash, HASH_PROC_DEFAULT)) return ifnone; + if (key == Qundef) return Qnil; + return rb_funcall(ifnone, id_yield, 2, hash, key); + } + else { + return rb_funcall(hash, id_default, 1, key); + } +} + /* * call-seq: * hsh[key] -> value @@ -500,13 +514,7 @@ rb_hash_aref(VALUE hash, VALUE key) st_data_t val; if (!RHASH(hash)->ntbl || !st_lookup(RHASH(hash)->ntbl, key, &val)) { - if (!FL_TEST(hash, HASH_PROC_DEFAULT) && - rb_method_basic_definition_p(CLASS_OF(hash), id_default)) { - return RHASH_IFNONE(hash); - } - else { - return rb_funcall(hash, id_default, 1, key); - } + return hash_default_value(hash, key); } return (VALUE)val; } @@ -865,12 +873,7 @@ rb_hash_shift(VALUE hash) return rb_assoc_new(var.key, var.val); } } - if (FL_TEST(hash, HASH_PROC_DEFAULT)) { - return rb_funcall(RHASH_IFNONE(hash), id_yield, 2, hash, Qnil); - } - else { - return RHASH_IFNONE(hash); - } + return hash_default_value(hash, Qnil); } static int |