[前][次][番号順一覧][スレッド一覧]

ruby-changes:60601

From: Jeremy <ko1@a...>
Date: Tue, 31 Mar 2020 16:31:54 +0900 (JST)
Subject: [ruby-changes:60601] bb93659fef (ruby_2_7): Fix pp when passed a empty ruby2_keywords-flagged hash as array element (#2966)

https://git.ruby-lang.org/ruby.git/commit/?id=bb93659fef

From bb93659fefd7f4557129043742771a33bd30c255 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Tue, 31 Mar 2020 00:10:57 -0700
Subject: 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@u...>

diff --git a/lib/pp.rb b/lib/pp.rb
index 81a9a16..012b328 100644
--- a/lib/pp.rb
+++ b/lib/pp.rb
@@ -223,7 +223,16 @@ class PP < PrettyPrint https://github.com/ruby/ruby/blob/trunk/lib/pp.rb#L223
         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 3262417..cd16af6 100644
--- a/test/test_pp.rb
+++ b/test/test_pp.rb
@@ -176,6 +176,11 @@ class PPSingleLineTest < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_pp.rb#L176
     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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]