summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-24 02:53:37 (GMT)
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-12-24 02:53:37 (GMT)
commit9c6eaad72372576a3d351bc6044e74814718c137 (patch)
treeb39b1af99ea3ffaf4fbf14eac36dd6d06cc6aca3 /hash.c
parent0cd829c3393a143ff72fa56ea4040a82e2ecf1e0 (diff)
* hash.c (rb_hash_delete): return Qnil if there are no corresponding
entry. [Bug #10623] * hash.c (rb_hash_delete_entry): try delete and return Qundef if there are no corresponding entry. * internal.h: add rb_hash_delete_entry()'s declaration. * symbol.c: use rb_hash_delete_entry(). * thread.c: use rb_hash_delete_entry(). * ext/-test-/hash/delete.c: use rb_hash_delete_entry(). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@48958 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c65
1 files changed, 49 insertions, 16 deletions
diff --git a/hash.c b/hash.c
index 1b9b5a2..bd49a1d 100644
--- a/hash.c
+++ b/hash.c
@@ -969,22 +969,48 @@ rb_hash_index(VALUE hash, VALUE value)
return rb_hash_key(hash, value);
}
+/*
+ * delete a specified entry a given key.
+ * if there is the corresponding entry, return a value of the entry.
+ * if there is no corresponding entry, return Qundef.
+ */
VALUE
-rb_hash_delete(VALUE hash, VALUE key)
+rb_hash_delete_entry(VALUE hash, VALUE key)
{
st_data_t ktmp = (st_data_t)key, val;
- if (!RHASH(hash)->ntbl)
- return Qundef;
- if (RHASH_ITER_LEV(hash) > 0) {
- if (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef)) {
- FL_SET(hash, HASH_DELETED);
- return (VALUE)val;
- }
+ if (!RHASH(hash)->ntbl) {
+ return Qundef;
}
- else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val))
+ else if (RHASH_ITER_LEV(hash) > 0 &&
+ (st_delete_safe(RHASH(hash)->ntbl, &ktmp, &val, (st_data_t)Qundef))) {
+ FL_SET(hash, HASH_DELETED);
return (VALUE)val;
- return Qundef;
+ }
+ else if (st_delete(RHASH(hash)->ntbl, &ktmp, &val)) {
+ return (VALUE)val;
+ }
+ else {
+ return Qundef;
+ }
+}
+
+/*
+ * delete a specified entry by a given key.
+ * if there is the corresponding entry, return a value of the entry.
+ * if there is no corresponding entry, return Qnil.
+ */
+VALUE
+rb_hash_delete(VALUE hash, VALUE key)
+{
+ VALUE deleted_value = rb_hash_delete_entry(hash, key);
+
+ if (deleted_value != Qundef) { /* likely pass */
+ return deleted_value;
+ }
+ else {
+ return Qnil;
+ }
}
/*
@@ -1011,12 +1037,19 @@ rb_hash_delete_m(VALUE hash, VALUE key)
VALUE val;
rb_hash_modify_check(hash);
- val = rb_hash_delete(hash, key);
- if (val != Qundef) return val;
- if (rb_block_given_p()) {
- return rb_yield(key);
+ val = rb_hash_delete_entry(hash, key);
+
+ if (val != Qundef) {
+ return val;
+ }
+ else {
+ if (rb_block_given_p()) {
+ return rb_yield(key);
+ }
+ else {
+ return Qnil;
+ }
}
- return Qnil;
}
struct shift_var {
@@ -1063,7 +1096,7 @@ rb_hash_shift(VALUE hash)
else {
rb_hash_foreach(hash, shift_i_safe, (VALUE)&var);
if (var.key != Qundef) {
- rb_hash_delete(hash, var.key);
+ rb_hash_delete_entry(hash, var.key);
return rb_assoc_new(var.key, var.val);
}
}