summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-31 05:23:01 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2012-03-31 05:23:01 +0000
commit160d02d830d93316a8b4afd54138c1a8bfb8a6b3 (patch)
tree10f355909c45a2d9bf76f3918964533519ce9fc7 /hash.c
parent15ca66efb0292388e2c8b6772bf0549a7c396eb9 (diff)
* 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.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/hash.c b/hash.c
index 08325a142e..4764bdd6b2 100644
--- a/hash.c
+++ b/hash.c
@@ -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