aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2020-03-31 00:10:57 -0700
committerGitHub <noreply@github.com>2020-03-31 16:10:57 +0900
commitbb93659fefd7f4557129043742771a33bd30c255 (patch)
tree6d9074b15d4873420b4111274220972b3fe2799d
parentd04856bdc502eec4055da1e5cf717639c314e189 (diff)
downloadruby-bb93659fefd7f4557129043742771a33bd30c255.tar.gz
Fix pp when passed a empty ruby2_keywords-flagged hash as array element (#2966)
This causes problems because the hash is passed to a block not accepting keywords. Because the hash is empty and keyword flagged, it is removed before calling the block. This doesn't cause an ArgumentError because it is a block and not a lambda. Just like any other block not passed required arguments, arguments not passed are set to nil. Issues like this are a strong reason not to have ruby2_keywords by default. Fixes [Bug #16519] This backports 28d31ead34baff1c4abc0d7d902ef4bc1d576fb2 and 0ea759eac9234afc47e8fb1bcacfe9ee12c8ffb6, but needed to be modified for 2.7 as 2.7 will perform empty keyword to positional hash conversion for required arguments, which will happen if "v" in the seplist method is empty when yielded. Co-authored-by: NARUSE, Yui <nurse@users.noreply.github.com>
-rw-r--r--lib/pp.rb11
-rw-r--r--test/test_pp.rb5
2 files changed, 15 insertions, 1 deletions
diff --git a/lib/pp.rb b/lib/pp.rb
index 81a9a1629c..012b328aad 100644
--- a/lib/pp.rb
+++ b/lib/pp.rb
@@ -223,7 +223,16 @@ class PP < PrettyPrint
else
sep.call
end
- yield(*v)
+ case v.last
+ when Hash
+ if Hash.ruby2_keywords_hash?(v.last)
+ yield(*v, **{})
+ else
+ yield(*v)
+ end
+ else
+ yield(*v)
+ end
}
end
diff --git a/test/test_pp.rb b/test/test_pp.rb
index 3262417fba..cd16af6394 100644
--- a/test/test_pp.rb
+++ b/test/test_pp.rb
@@ -176,6 +176,11 @@ class PPSingleLineTest < Test::Unit::TestCase
assert_equal("{1=>1}", PP.singleline_pp({ 1 => 1}, ''.dup)) # [ruby-core:02699]
assert_equal("[1#{', 1'*99}]", PP.singleline_pp([1]*100, ''.dup))
end
+
+ def test_hash_in_array
+ assert_equal("[{}]", PP.singleline_pp([->(*a){a.last}.ruby2_keywords.call(**{})], ''.dup))
+ assert_equal("[{}]", PP.singleline_pp([Hash.ruby2_keywords_hash({})], ''.dup))
+ end
end
class PPDelegateTest < Test::Unit::TestCase