diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-07 02:16:04 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2013-12-07 02:16:04 +0000 |
commit | 7416073cded9976e7b87d142cca79ce2b0fcc845 (patch) | |
tree | 21793d331381dad60abda6eb4394ccd211d3cbd6 /hash.c | |
parent | 77280b6cd66467c7ff7f04c4849dd4a5181d5397 (diff) | |
download | ruby-7416073cded9976e7b87d142cca79ce2b0fcc845.tar.gz |
hash.c: rb_hash_reject without dup
* hash.c (rb_hash_reject): copy unrejected elements only to new hash,
so that the change on the original receiver can affect.
[ruby-core:58914] [Bug #9223]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@44047 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 18 |
1 files changed, 17 insertions, 1 deletions
@@ -1092,6 +1092,15 @@ rb_hash_reject_bang(VALUE hash) return hash; } +static int +reject_i(VALUE key, VALUE value, VALUE hash) +{ + if (!RTEST(rb_yield_values(2, key, value))) { + rb_hash_aset(hash, key, value); + } + return ST_CONTINUE; +} + /* * call-seq: * hsh.reject {| key, value | block } -> a_hash @@ -1106,7 +1115,14 @@ rb_hash_reject_bang(VALUE hash) static VALUE rb_hash_reject(VALUE hash) { - return rb_hash_delete_if(rb_obj_dup(hash)); + VALUE ret; + + RETURN_SIZED_ENUMERATOR(hash, 0, 0, hash_enum_size); + ret = hash_alloc(rb_obj_class(hash)); + if (!RHASH_EMPTY_P(hash)) { + rb_hash_foreach(hash, reject_i, ret); + } + return ret; } /* |