summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/hash.c b/hash.c
index c9f741f2ec..40866509d1 100644
--- a/hash.c
+++ b/hash.c
@@ -1801,6 +1801,8 @@ rb_hash_initialize(int argc, VALUE *argv, VALUE hash)
return hash;
}
+static VALUE rb_hash_to_a(VALUE hash);
+
/*
* call-seq:
* Hash[] -> new_empty_hash
@@ -1844,12 +1846,22 @@ rb_hash_s_create(int argc, VALUE *argv, VALUE klass)
if (argc == 1) {
tmp = rb_hash_s_try_convert(Qnil, argv[0]);
if (!NIL_P(tmp)) {
- hash = hash_alloc(klass);
- hash_copy(hash, tmp);
- return hash;
+ if (!RHASH_EMPTY_P(tmp) && rb_hash_compare_by_id_p(tmp)) {
+ /* hash_copy for non-empty hash will copy compare_by_identity
+ flag, but we don't want it copied. Work around by
+ converting hash to flattened array and using that. */
+ tmp = rb_hash_to_a(tmp);
+ }
+ else {
+ hash = hash_alloc(klass);
+ hash_copy(hash, tmp);
+ return hash;
+ }
+ }
+ else {
+ tmp = rb_check_array_type(argv[0]);
}
- tmp = rb_check_array_type(argv[0]);
if (!NIL_P(tmp)) {
long i;