From 2d53296e44d66eea35924bcc9471dbcdd15e7d41 Mon Sep 17 00:00:00 2001 From: ccocchi Date: Sun, 10 Oct 2021 17:25:30 +0200 Subject: [PATCH 1/5] Allow Hash#transform_keys to take a hash argument --- src/main/ruby/truffleruby/core/hash.rb | 29 ++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/ruby/truffleruby/core/hash.rb b/src/main/ruby/truffleruby/core/hash.rb index 32fbe06eb62a..d7b35367aa09 100644 --- a/src/main/ruby/truffleruby/core/hash.rb +++ b/src/main/ruby/truffleruby/core/hash.rb @@ -539,25 +539,42 @@ def transform_values! self end - def transform_keys - return to_enum(:transform_keys) { size } unless block_given? + def transform_keys(mapping = nil) + has_block = block_given? + return to_enum(:transform_keys) { size } unless mapping || has_block + + mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) if mapping h = {} each_pair do |key, value| - h[yield(key)] = value + if mapping + k = Primitive.hash_get_or_undefined(mapping, key) + k = has_block ? yield(key) : key if Primitive.undefined?(k) + h[k] = value + else + h[yield(key)] = value + end end h end - def transform_keys! - return to_enum(:transform_keys!) { size } unless block_given? + def transform_keys!(mapping = nil) + has_block = block_given? + return to_enum(:transform_keys!) { size } unless mapping || has_block Primitive.check_frozen self + mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) if mapping h = {} begin each_pair do |key, value| - h[yield(key)] = value + if mapping + k = Primitive.hash_get_or_undefined(mapping, key) + k = has_block ? yield(key) : key if Primitive.undefined?(k) + h[k] = value + else + h[yield(key)] = value + end end ensure replace h From 05462d0fd032d1bbe0f0bc31702f8190b4918285 Mon Sep 17 00:00:00 2001 From: ccocchi Date: Wed, 13 Oct 2021 21:35:49 +0200 Subject: [PATCH 2/5] Move boolean condition check outside of loop --- src/main/ruby/truffleruby/core/hash.rb | 29 +++++++++++++++----------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/src/main/ruby/truffleruby/core/hash.rb b/src/main/ruby/truffleruby/core/hash.rb index d7b35367aa09..1f35548162dc 100644 --- a/src/main/ruby/truffleruby/core/hash.rb +++ b/src/main/ruby/truffleruby/core/hash.rb @@ -541,20 +541,23 @@ def transform_values! def transform_keys(mapping = nil) has_block = block_given? - return to_enum(:transform_keys) { size } unless mapping || has_block - - mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) if mapping - h = {} - each_pair do |key, value| - if mapping + + if mapping + mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) + each_pair do |key, value| k = Primitive.hash_get_or_undefined(mapping, key) k = has_block ? yield(key) : key if Primitive.undefined?(k) h[k] = value - else + end + else + return to_enum(:transform_keys) { size } unless has_block + + each_pair do |key, value| h[yield(key)] = value end end + h end @@ -563,16 +566,18 @@ def transform_keys!(mapping = nil) return to_enum(:transform_keys!) { size } unless mapping || has_block Primitive.check_frozen self - mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) if mapping - h = {} + begin - each_pair do |key, value| - if mapping + if mapping + mapping = Truffle::Type.coerce_to(mapping, Hash, :to_hash) + each_pair do |key, value| k = Primitive.hash_get_or_undefined(mapping, key) k = has_block ? yield(key) : key if Primitive.undefined?(k) h[k] = value - else + end + else + each_pair do |key, value| h[yield(key)] = value end end From b9aa5b08b7cd7e2b7605f87573f02bf5e5dc2e90 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 21 Oct 2021 13:23:10 +0200 Subject: [PATCH 3/5] Untag passing transform_keys specs --- spec/tags/core/hash/transform_keys_tags.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/spec/tags/core/hash/transform_keys_tags.txt b/spec/tags/core/hash/transform_keys_tags.txt index 979402633bb8..897d63823eb4 100644 --- a/spec/tags/core/hash/transform_keys_tags.txt +++ b/spec/tags/core/hash/transform_keys_tags.txt @@ -1,6 +1 @@ fails:Hash#transform_keys! returns the processed keys and non evaluated keys if we broke from the block -fails:Hash#transform_keys allows a hash argument -fails:Hash#transform_keys allows a partial transformation of keys when using a hash argument -fails:Hash#transform_keys allows a combination of hash and block argument -fails:Hash#transform_keys! allows a hash argument -fails:Hash#transform_keys! on frozen instance raises a FrozenError on hash argument From c3fee895696718681909ee31e27ad5409c661290 Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 21 Oct 2021 13:33:36 +0200 Subject: [PATCH 4/5] Remove old warning for jt untag * It is reliable now. --- tool/jt.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/tool/jt.rb b/tool/jt.rb index 4941d461f473..784b3c48cdc2 100755 --- a/tool/jt.rb +++ b/tool/jt.rb @@ -1637,9 +1637,6 @@ def purge(path, *args) def untag(path, *args) require_ruby_launcher! - puts - puts "WARNING: untag is currently not very reliable - run `jt test #{[path,*args] * ' '}` after and manually annotate any new failures" - puts test_specs('untag', path, *args) end From c0fa69526b202efb1fc38bce1874208f563aba5a Mon Sep 17 00:00:00 2001 From: Benoit Daloze Date: Thu, 21 Oct 2021 13:39:41 +0200 Subject: [PATCH 5/5] Add ChangeLog entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3abbd17d041d..6b5f06711d78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ Compatibility: * `Module#attr_*` methods now return an array of method names (#2498, @gogainda). * Fixed `Socket#(local|remote)_address` to retrieve family and type from the file descriptor (#2444, @larskanis). * Add `Thread.ignore_deadlock` accessor (#2453). +* Allow `Hash#transform_keys` to take a hash argument (@ccocchi, #2464). Performance: