diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-24 02:53:37 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2014-12-24 02:53:37 +0000 |
commit | 9c6eaad72372576a3d351bc6044e74814718c137 (patch) | |
tree | b39b1af99ea3ffaf4fbf14eac36dd6d06cc6aca3 /hash.c | |
parent | 0cd829c3393a143ff72fa56ea4040a82e2ecf1e0 (diff) | |
download | ruby-9c6eaad72372576a3d351bc6044e74814718c137.tar.gz |
* 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.c | 65 |
1 files changed, 49 insertions, 16 deletions
@@ -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); } } |