Skip to content

Commit

Permalink
Copy compare_by_identity flag for empty hashes in Hash.ruby2_keywords…
Browse files Browse the repository at this point in the history
…_hash

This was already copied for non-empty hashes.  As Hash.ruby2_keywords_hash
copies default values, it should also copy the compare_by_identity flag.

Partially Fixes [Bug #19113]
  • Loading branch information
jeremyevans committed Mar 24, 2023
1 parent d3197de commit 1b13db2
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 3 deletions.
9 changes: 6 additions & 3 deletions hash.c
Expand Up @@ -1972,9 +1972,12 @@ static VALUE
rb_hash_s_ruby2_keywords_hash(VALUE dummy, VALUE hash)
{
Check_Type(hash, T_HASH);
hash = rb_hash_dup(hash);
RHASH(hash)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
return hash;
VALUE tmp = rb_hash_dup(hash);
if (RHASH_EMPTY_P(hash) && rb_hash_compare_by_id_p(hash)) {
rb_hash_compare_by_id(tmp);
}
RHASH(tmp)->basic.flags |= RHASH_PASS_AS_KEYWORDS;
return tmp;
}

struct rehash_arg {
Expand Down
24 changes: 24 additions & 0 deletions spec/ruby/core/hash/ruby2_keywords_hash_spec.rb
Expand Up @@ -56,4 +56,28 @@
it "raises TypeError for non-Hash" do
-> { Hash.ruby2_keywords_hash(nil) }.should raise_error(TypeError)
end

it "retains the default value" do
hash = Hash.new(1)
Hash.ruby2_keywords_hash(hash).default.should == 1
hash[:a] = 1
Hash.ruby2_keywords_hash(hash).default.should == 1
end

it "retains the default_proc" do
pr = proc { |h, k| h[k] = [] }
hash = Hash.new(&pr)
Hash.ruby2_keywords_hash(hash).default_proc.should == pr
hash[:a] = 1
Hash.ruby2_keywords_hash(hash).default_proc.should == pr
end

ruby_version_is '3.3' do
it "retains compare_by_identity_flag" do
hash = {}.compare_by_identity
Hash.ruby2_keywords_hash(hash).compare_by_identity?.should == true
hash[:a] = 1
Hash.ruby2_keywords_hash(hash).compare_by_identity?.should == true
end
end
end

0 comments on commit 1b13db2

Please sign in to comment.