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

ruby-changes:71448

From: Nobuyoshi <ko1@a...>
Date: Thu, 17 Mar 2022 23:18:52 +0900 (JST)
Subject: [ruby-changes:71448] e660b934b9 (master): A positional Hash is not keyword arguments [Bug #18632]

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

From e660b934b98943826f888f2b73f773c6411cd199 Mon Sep 17 00:00:00 2001
From: Nobuyoshi Nakada <nobu@r...>
Date: Thu, 17 Mar 2022 18:54:49 +0900
Subject: A positional Hash is not keyword arguments [Bug #18632]

---
 spec/ruby/core/struct/new_spec.rb | 9 +++++++--
 struct.c                          | 8 ++++----
 test/ruby/test_struct.rb          | 5 +++--
 3 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/spec/ruby/core/struct/new_spec.rb b/spec/ruby/core/struct/new_spec.rb
index cbbec829d7..fdbf8c2c91 100644
--- a/spec/ruby/core/struct/new_spec.rb
+++ b/spec/ruby/core/struct/new_spec.rb
@@ -60,10 +60,15 @@ describe "Struct.new" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/struct/new_spec.rb#L60
     -> { Struct.new(:animal, nil)                  }.should raise_error(TypeError)
     -> { Struct.new(:animal, true)                 }.should raise_error(TypeError)
     -> { Struct.new(:animal, ['chris', 'evan'])    }.should raise_error(TypeError)
+    ruby_version_is "3.2" do
+      -> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(TypeError)
+    end
   end
 
-  it "raises a ArgumentError if passed a Hash with an unknown key" do
-    -> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
+  ruby_version_is ""..."3.2" do
+    it "raises a ArgumentError if passed a Hash with an unknown key" do
+      -> { Struct.new(:animal, { name: 'chris' }) }.should raise_error(ArgumentError)
+    end
   end
 
   it "raises ArgumentError when there is a duplicate member" do
diff --git a/struct.c b/struct.c
index 8b19266e62..3610ecfc10 100644
--- a/struct.c
+++ b/struct.c
@@ -576,8 +576,9 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L576
     long i;
     VALUE st;
     st_table *tbl;
+    VALUE opt;
 
-    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
+    argc = rb_scan_args(argc, argv, "1*:", NULL, NULL, &opt);
     name = argv[0];
     if (SYMBOL_P(name)) {
 	name = Qnil;
@@ -587,20 +588,19 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L588
 	++argv;
     }
 
-    if (RB_TYPE_P(argv[argc-1], T_HASH)) {
+    if (!NIL_P(opt)) {
 	static ID keyword_ids[1];
 
 	if (!keyword_ids[0]) {
 	    keyword_ids[0] = rb_intern("keyword_init");
 	}
-        rb_get_kwargs(argv[argc-1], keyword_ids, 0, 1, &keyword_init);
+        rb_get_kwargs(opt, keyword_ids, 0, 1, &keyword_init);
         if (keyword_init == Qundef) {
             keyword_init = Qnil;
         }
         else if (RTEST(keyword_init)) {
             keyword_init = Qtrue;
         }
-	--argc;
     }
 
     rest = rb_ident_hash_new();
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index 5b7b8c7255..78a81c5200 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -100,8 +100,9 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L100
     assert_equal([:utime, :stime, :cutime, :cstime], Process.times.members)
   end
 
-  def test_struct_new_with_empty_hash
-    assert_equal({:a=>1}, Struct.new(:a, {}).new({:a=>1}).a)
+  def test_struct_new_with_hash
+    assert_raise_with_message(TypeError, /not a symbol/) {Struct.new(:a, {})}
+    assert_raise_with_message(TypeError, /not a symbol/) {Struct.new(:a, {name: "b"})}
   end
 
   def test_struct_new_with_keyword_init
-- 
cgit v1.2.1


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

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