зеркало из https://github.com/github/ruby.git
Change Hash#compact to keep default values and compare_by_identity flag
The documentation states it returns a copy of self with nil value entries removed. However, the previous behavior was creating a plain new hash with non-nil values copied into it. This change aligns the behavior with the documentation. Fixes [Bug #19113]
This commit is contained in:
Родитель
1b13db25d8
Коммит
5d6579bd91
16
hash.c
16
hash.c
|
@ -4307,15 +4307,6 @@ delete_if_nil(VALUE key, VALUE value, VALUE hash)
|
|||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static int
|
||||
set_if_not_nil(VALUE key, VALUE value, VALUE hash)
|
||||
{
|
||||
if (!NIL_P(value)) {
|
||||
rb_hash_aset(hash, key, value);
|
||||
}
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* hash.compact -> new_hash
|
||||
|
@ -4329,9 +4320,12 @@ set_if_not_nil(VALUE key, VALUE value, VALUE hash)
|
|||
static VALUE
|
||||
rb_hash_compact(VALUE hash)
|
||||
{
|
||||
VALUE result = rb_hash_new();
|
||||
VALUE result = rb_hash_dup(hash);
|
||||
if (!RHASH_EMPTY_P(hash)) {
|
||||
rb_hash_foreach(hash, set_if_not_nil, result);
|
||||
rb_hash_foreach(result, delete_if_nil, result);
|
||||
}
|
||||
else if (rb_hash_compare_by_id_p(hash)) {
|
||||
result = rb_hash_compare_by_id(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,30 @@ describe "Hash#compact" do
|
|||
@hash.compact
|
||||
@hash.should == @initial_pairs
|
||||
end
|
||||
|
||||
ruby_version_is '3.3' do
|
||||
it "retains the default value" do
|
||||
hash = Hash.new(1)
|
||||
hash.compact.default.should == 1
|
||||
hash[:a] = 1
|
||||
hash.compact.default.should == 1
|
||||
end
|
||||
|
||||
it "retains the default_proc" do
|
||||
pr = proc { |h, k| h[k] = [] }
|
||||
hash = Hash.new(&pr)
|
||||
hash.compact.default_proc.should == pr
|
||||
hash[:a] = 1
|
||||
hash.compact.default_proc.should == pr
|
||||
end
|
||||
|
||||
it "retains compare_by_identity_flag" do
|
||||
hash = {}.compare_by_identity
|
||||
hash.compact.compare_by_identity?.should == true
|
||||
hash[:a] = 1
|
||||
hash.compact.compare_by_identity?.should == true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe "Hash#compact!" do
|
||||
|
|
Загрузка…
Ссылка в новой задаче