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

ruby-changes:57996

From: Jeremy <ko1@a...>
Date: Sat, 28 Sep 2019 03:22:38 +0900 (JST)
Subject: [ruby-changes:57996] d53cf85474 (master): Fix warning when doing Struct.new(:x, keyword_init: true){}

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

From d53cf854741bbf496298c5a722988d2dd84314a1 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Fri, 27 Sep 2019 08:07:49 -0700
Subject: Fix warning when doing Struct.new(:x, keyword_init: true){}

This is due to calling rb_mod_module_eval directly instead of using
rb_funcall_passing_block.

The problem with calling directly is it does not create a new VM
frame, so rb_mod_module_eval was called with no arguments, but with
the keyword given VM frame flag set, which causes problems
internally.

diff --git a/struct.c b/struct.c
index de40701..3a631ab 100644
--- a/struct.c
+++ b/struct.c
@@ -569,7 +569,7 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L569
     setup_struct(st, rest);
     rb_ivar_set(st, id_keyword_init, keyword_init);
     if (rb_block_given_p()) {
-	rb_mod_module_eval(0, 0, st);
+        rb_funcall_passing_block(st, rb_intern("module_eval"), 0, 0);
     }
 
     return st;
diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb
index ec0a290..6ba2815 100644
--- a/test/ruby/test_struct.rb
+++ b/test/ruby/test_struct.rb
@@ -119,6 +119,16 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L119
     end
   end
 
+  def test_struct_new_with_keyword_init_and_block
+    struct = @Struct.new(:a, :b, keyword_init: true) do
+      def c
+        a + b
+      end
+    end
+
+    assert_equal(3, struct.new(a: 1, b: 2).c)
+  end
+
   def test_initialize
     klass = @Struct.new(:a)
     assert_raise(ArgumentError) { klass.new(1, 2) }
-- 
cgit v0.10.2


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

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