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

ruby-changes:57597

From: Yusuke <ko1@a...>
Date: Fri, 6 Sep 2019 14:05:13 +0900 (JST)
Subject: [ruby-changes:57597] 55b96c5d2d (master): Add a keyword-to-last-hash warning for some case of define_method method

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

From 55b96c5d2d7d8bcc2953484bd2f9c9519b252dae Mon Sep 17 00:00:00 2001
From: Yusuke Endoh <mame@r...>
Date: Thu, 5 Sep 2019 19:29:25 +0900
Subject: Add a keyword-to-last-hash warning for some case of define_method
 method

and lambda.

When define_method is a simple iseq (`define_method(:m) {|x| ... }`),
passing keywords to it (`m(**kw)`) didn't print a warning.

diff --git a/test/ruby/test_keyword.rb b/test/ruby/test_keyword.rb
index 229f0b3..71b72bd 100644
--- a/test/ruby/test_keyword.rb
+++ b/test/ruby/test_keyword.rb
@@ -185,20 +185,42 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L185
 
     f = -> { true }
     assert_equal(true, f[**{}])
-    assert_raise(ArgumentError) { f[**kw] }
-    assert_raise(ArgumentError) { f[**h] }
-    assert_raise(ArgumentError) { f[a: 1] }
-    assert_raise(ArgumentError) { f[**h2] }
-    assert_raise(ArgumentError) { f[**h3] }
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { f[**kw] }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { f[**h] }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { f[a: 1] }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { f[**h2] }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { f[**h3] }
+    end
 
     f = ->(a) { a }
     assert_raise(ArgumentError) { f[**{}] }
-    assert_equal(kw, f[**kw])
-    assert_equal(h, f[**h])
-    assert_equal(h, f[a: 1])
-    assert_equal(h2, f[**h2])
-    assert_equal(h3, f[**h3])
-    assert_equal(h3, f[a: 1, **h2])
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(kw, f[**kw])
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h, f[**h])
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h, f[a: 1])
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h2, f[**h2])
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h3, f[**h3])
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h3, f[a: 1, **h2])
+    end
 
     f = ->(**x) { x }
     assert_equal(kw, f[**{}])
@@ -685,24 +707,48 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L707
       define_method(:m) { }
     end
     assert_nil(c.m(**{}))
-    assert_raise(ArgumentError) { c.m(**kw) }
-    assert_raise(ArgumentError) { c.m(**h) }
-    assert_raise(ArgumentError) { c.m(a: 1) }
-    assert_raise(ArgumentError) { c.m(**h2) }
-    assert_raise(ArgumentError) { c.m(**h3) }
-    assert_raise(ArgumentError) { c.m(a: 1, **h2) }
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(**kw) }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(**h) }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(a: 1) }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(**h2) }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(**h3) }
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_raise(ArgumentError) { c.m(a: 1, **h2) }
+    end
 
     c = Object.new
     class << c
       define_method(:m) {|arg| arg }
     end
     assert_raise(ArgumentError) { c.m(**{}) }
-    assert_equal(kw, c.m(**kw))
-    assert_equal(h, c.m(**h))
-    assert_equal(h, c.m(a: 1))
-    assert_equal(h2, c.m(**h2))
-    assert_equal(h3, c.m(**h3))
-    assert_equal(h3, c.m(a: 1, **h2))
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(kw, c.m(**kw))
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h, c.m(**h))
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h, c.m(a: 1))
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h2, c.m(**h2))
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h3, c.m(**h3))
+    end
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal(h3, c.m(a: 1, **h2))
+    end
 
     c = Object.new
     class << c
@@ -1211,10 +1257,14 @@ class TestKeywordArguments < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_keyword.rb#L1257
 
     o = Object.new
     def o.to_hash() { a: 1 } end
-    assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898)
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal({a: 1}, m1(**o) {|x| break x}, bug9898)
+    end
     o2 = Object.new
     def o2.to_hash() { b: 2 } end
-    assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898)
+    assert_warn(/The keyword argument is passed as the last hash parameter/m) do
+      assert_equal({a: 1, b: 2}, m1(**o, **o2) {|x| break x}, bug9898)
+    end
   end
 
   def test_implicit_hash_conversion
diff --git a/vm_insnhelper.c b/vm_insnhelper.c
index 92a9bc6..baf93de 100644
--- a/vm_insnhelper.c
+++ b/vm_insnhelper.c
@@ -2929,6 +2929,10 @@ vm_callee_setup_block_arg(rb_execution_context_t *ec, struct rb_calling_info *ca https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2929
 
 	CALLER_SETUP_ARG(cfp, calling, ci, 0); /* splat arg */
 
+        if (calling->kw_splat) {
+            rb_warn_keyword_to_last_hash(calling, ci, iseq);
+        }
+
 	if (arg_setup_type == arg_setup_block &&
 	    calling->argc == 1 &&
 	    iseq->body->param.flags.has_lead &&
-- 
cgit v0.10.2


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

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