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

ruby-changes:70607

From: Nobuyoshi <ko1@a...>
Date: Mon, 27 Dec 2021 00:41:45 +0900 (JST)
Subject: [ruby-changes:70607] c956f979e5 (master): Initialize Struct by calling with keyword arguments

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

From c956f979e5d05900315d2753d5c3b1389af8dae4 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Sun, 26 Dec 2021 22:39:48 +0900
Subject: Initialize Struct by calling with keyword arguments

---
 struct.c                 | 23 ++++++++++++++++-------
 test/ruby/test_struct.rb |  5 ++---
 2 files changed, 18 insertions(+), 10 deletions(-)

diff --git a/struct.c b/struct.c
index 716bc7f4fd9..1bc98003899 100644
--- a/struct.c
+++ b/struct.c
@@ -685,12 +685,25 @@ rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/struct.c#L685
         return Qnil;
     }
 
-    VALUE keyword_init = rb_struct_s_keyword_init(klass);
-    if (RTEST(keyword_init)) {
-	struct struct_hash_set_arg arg;
+    bool keyword_init = false;
+    switch (rb_struct_s_keyword_init(klass)) {
+      default:
 	if (argc > 1 || !RB_TYPE_P(argv[0], T_HASH)) {
 	    rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0)", argc);
 	}
+	keyword_init = true;
+	break;
+      case Qfalse:
+        break;
+      case Qnil:
+	if (argc > 1 || !RB_TYPE_P(argv[0], T_HASH)) {
+            break;
+        }
+	keyword_init = rb_keyword_given_p();
+        break;
+    }
+    if (keyword_init) {
+	struct struct_hash_set_arg arg;
 	rb_mem_clear((VALUE *)RSTRUCT_CONST_PTR(self), n);
 	arg.self = self;
 	arg.unknown_keywords = Qnil;
@@ -704,10 +717,6 @@ rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self) https://github.com/ruby/ruby/blob/trunk/struct.c#L717
 	if (n < argc) {
 	    rb_raise(rb_eArgError, "struct size differs");
 	}
-        if (NIL_P(keyword_init) && argc == 1 && RB_TYPE_P(argv[0], T_HASH) && rb_keyword_given_p()) {
-            rb_warn("Passing only keyword arguments to Struct#initialize will behave differently from Ruby 3.2. "\
-                    "Please use a Hash literal like .new({k: v}) instead of .new(k: v).");
-        }
         for (long i=0; i<argc; i++) {
 	    RSTRUCT_SET(self, i, argv[i]);
 	}
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index 176e2ac5dec..5b7b8c72557 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -362,9 +362,8 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L362
   end
 
   def test_keyword_args_warning
-    warning = /warning: Passing only keyword arguments to Struct#initialize will behave differently from Ruby 3\.2\./
-    assert_warn(warning) { assert_equal({a: 1}, @Struct.new(:a).new(a: 1).a) }
-    assert_warn(warning) { assert_equal({a: 1}, @Struct.new(:a, keyword_init: nil).new(a: 1).a) }
+    assert_warn('') { assert_equal(1, @Struct.new(:a).new(a: 1).a) }
+    assert_warn('') { assert_equal(1, @Struct.new(:a, keyword_init: nil).new(a: 1).a) }
     assert_warn('') { assert_equal({a: 1}, @Struct.new(:a).new({a: 1}).a) }
     assert_warn('') { assert_equal({a: 1}, @Struct.new(:a, :b).new(1, a: 1).b) }
     assert_warn('') { assert_equal(1, @Struct.new(:a, keyword_init: true).new(a: 1).a) }
-- 
cgit v1.2.1


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

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