From: "shyouhei (Shyouhei Urabe)" Date: 2012-03-29T11:44:29+09:00 Subject: [ruby-core:43837] [ruby-trunk - Feature #6219] Return value of Hash#store Issue #6219 has been updated by shyouhei (Shyouhei Urabe). =begin Hmm, here you are a patch (not tested though). From c55a9c9fab30d51be77821bce36054fe365b49af Mon Sep 17 00:00:00 2001 Message-Id: From: URABE, Shyouhei Date: Thu, 29 Mar 2012 11:38:17 +0900 Subject: [PATCH 1/1] Hash#store to return former content [feature #6219] Signed-off-by: URABE, Shyouhei diff --git a/hash.c b/hash.c index e9937ff..0cd4e43 100644 --- a/hash.c +++ b/hash.c @@ -1099,6 +1099,20 @@ copy_str_key(st_data_t str) return (st_data_t)rb_str_new4((VALUE)str); } +struct hash_aset_tuple { + st_data_t old; + st_data_t new; +}; + +static int +hash_aset_i(st_data_t key, st_data_t *value, st_data_t arg) +{ + struct hash_aset_tuple *ptr = (void *)arg; + ptr->old = *value; + *value = ptr->new; + return ST_CONTINUE; +} + /* * call-seq: * hsh[key] = value -> value @@ -1120,15 +1134,19 @@ copy_str_key(st_data_t str) VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val) { + struct hash_aset_tuple t; rb_hash_modify(hash); hash_update(hash, key); + t.new = val; + t.old = Qundef; if (RHASH(hash)->ntbl->type == &identhash || rb_obj_class(key) != rb_cString) { - st_insert(RHASH(hash)->ntbl, key, val); + st_update(RHASH(hash)->ntbl, key, hash_aset_i, (st_data_t)&t); } else { - st_insert2(RHASH(hash)->ntbl, key, val, copy_str_key); + st_data_t k = copy_str_key(key); + st_update(RHASH(hash)->ntbl, k, hash_aset_i, (st_data_t)&t); } - return val; + return t.old; } static int -- 1.7.0.4 =end ---------------------------------------- Feature #6219: Return value of Hash#store https://bugs.ruby-lang.org/issues/6219#change-25347 Author: MartinBosslet (Martin Bosslet) Status: Open Priority: Low Assignee: Category: core Target version: Hash#store returns the value that was just assigned, for example: h[:a] = b # => b Does anyone rely on this behavior, are there cases when this becomes handy? If however the return value is discarded most of the time, I was thinking it might be beneficial if we would return the previous value of a given key (nil if none was assigned yet) instead. That way we could assign and check for a collision in one pass, something that right now can only be done in two separate steps. -- http://bugs.ruby-lang.org/