Hash#replace to preserve order; close #2001

This commit is contained in:
Yukihiro "Matz" Matsumoto
2014-04-04 10:50:42 +09:00
parent 7a9630a5bb
commit 28ab106292
2 changed files with 14 additions and 54 deletions
+14
View File
@@ -142,6 +142,20 @@ class Hash
self.__init_core(block, *args)
end
##
# Replaces the contents of <i>hsh</i> with the contents of other hash
#
# ISO 15.2.13.4.23
def replace(hash)
self.clear
hash.each_key{|k|
self[k] = hash[k]
}
self
end
# ISO 15.2.13.4.17
alias initialize_copy replace
##
# Return a hash which contains the content of
# +self+ and +other+. If a block is given
-54
View File
@@ -337,12 +337,6 @@ mrb_hash_init_core(mrb_state *mrb, mrb_value hash)
return hash;
}
static mrb_value
to_hash(mrb_state *mrb, mrb_value hash)
{
return mrb_convert_type(mrb, hash, MRB_TT_HASH, "Hash", "to_hash");
}
/* 15.2.13.4.2 */
/*
* call-seq:
@@ -639,52 +633,6 @@ mrb_hash_aset(mrb_state *mrb, mrb_value self)
return val;
}
/* 15.2.13.4.17 */
/* 15.2.13.4.23 */
/*
* call-seq:
* hsh.replace(other_hash) -> hsh
*
* Replaces the contents of <i>hsh</i> with the contents of
* <i>other_hash</i>.
*
* h = { "a" => 100, "b" => 200 }
* h.replace({ "c" => 300, "d" => 400 }) #=> {"c"=>300, "d"=>400}
*
*/
static mrb_value
mrb_hash_replace(mrb_state *mrb, mrb_value hash)
{
mrb_value hash2, ifnone;
khash_t(ht) *h2;
khiter_t k;
mrb_get_args(mrb, "o", &hash2);
hash2 = to_hash(mrb, hash2);
if (mrb_obj_equal(mrb, hash, hash2)) return hash;
mrb_hash_clear(mrb, hash);
h2 = RHASH_TBL(hash2);
if (h2) {
for (k = kh_begin(h2); k != kh_end(h2); k++) {
if (kh_exist(h2, k))
mrb_hash_set(mrb, hash, kh_key(h2, k), kh_value(h2, k).v);
}
}
if (MRB_RHASH_PROCDEFAULT_P(hash2)) {
RHASH(hash)->flags |= MRB_HASH_PROC_DEFAULT;
ifnone = RHASH_PROCDEFAULT(hash2);
}
else {
ifnone = RHASH_IFNONE(hash2);
}
mrb_iv_set(mrb, hash, mrb_intern_lit(mrb, "ifnone"), ifnone);
return hash;
}
/* 15.2.13.4.20 */
/* 15.2.13.4.25 */
/*
@@ -902,12 +850,10 @@ mrb_init_hash(mrb_state *mrb)
mrb_define_method(mrb, h, "has_value?", mrb_hash_has_value, MRB_ARGS_REQ(1)); /* 15.2.13.4.14 */
mrb_define_method(mrb, h, "include?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.15 */
mrb_define_method(mrb, h, "__init_core", mrb_hash_init_core, MRB_ARGS_ANY()); /* core of 15.2.13.4.16 */
mrb_define_method(mrb, h, "initialize_copy", mrb_hash_replace, MRB_ARGS_REQ(1)); /* 15.2.13.4.17 */
mrb_define_method(mrb, h, "key?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.18 */
mrb_define_method(mrb, h, "keys", mrb_hash_keys, MRB_ARGS_NONE()); /* 15.2.13.4.19 */
mrb_define_method(mrb, h, "length", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.20 */
mrb_define_method(mrb, h, "member?", mrb_hash_has_key, MRB_ARGS_REQ(1)); /* 15.2.13.4.21 */
mrb_define_method(mrb, h, "replace", mrb_hash_replace, MRB_ARGS_REQ(1)); /* 15.2.13.4.23 */
mrb_define_method(mrb, h, "shift", mrb_hash_shift, MRB_ARGS_NONE()); /* 15.2.13.4.24 */
mrb_define_method(mrb, h, "dup", mrb_hash_dup, MRB_ARGS_NONE());
mrb_define_method(mrb, h, "size", mrb_hash_size_m, MRB_ARGS_NONE()); /* 15.2.13.4.25 */