ruby-changes:62397
From: nagachika <ko1@a...>
Date: Sun, 26 Jul 2020 17:59:53 +0900 (JST)
Subject: [ruby-changes:62397] 61c6d43306 (ruby_2_7): partially merge revision adf709a78534c1483ba851ccb0490464ca31503c: [Backport #16801]
https://git.ruby-lang.org/ruby.git/commit/?id=61c6d43306 From 61c6d433060881e952140d2154c06f8c9803dc8a Mon Sep 17 00:00:00 2001 From: nagachika <nagachika@r...> Date: Sun, 26 Jul 2020 17:45:27 +0900 Subject: partially merge revision adf709a78534c1483ba851ccb0490464ca31503c: [Backport #16801] Classes made from Struct should have default new singleton method. Co-authored-by: Yusuke Endoh mame@r... Co-authored-by: John Hawthorn john@h... Co-authored-by: Adam Hess HParker@g... Co-authored-by: Jose Cortinas jacortinas@g... Co-authored-by: Jean Boussier jean.boussier@g... diff --git a/struct.c b/struct.c index d1aa7c2..3fb5649 100644 --- a/struct.c +++ b/struct.c @@ -316,18 +316,15 @@ struct_new_kw(int argc, const VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L316 } static VALUE -setup_struct(VALUE nstr, VALUE members, int keyword_init) +setup_struct(VALUE nstr, VALUE members) { long i, len; - VALUE (*new_func)(int, const VALUE *, VALUE) = rb_class_new_instance; - - if (keyword_init) new_func = struct_new_kw; members = struct_set_members(nstr, members); rb_define_alloc_func(nstr, struct_alloc); - rb_define_singleton_method(nstr, "new", new_func, -1); - rb_define_singleton_method(nstr, "[]", new_func, -1); + rb_define_singleton_method(nstr, "new", struct_new_kw, -1); + rb_define_singleton_method(nstr, "[]", struct_new_kw, -1); rb_define_singleton_method(nstr, "members", rb_struct_s_members_m, 0); rb_define_singleton_method(nstr, "inspect", rb_struct_s_inspect, 0); len = RARRAY_LEN(members); @@ -442,7 +439,7 @@ rb_struct_define(const char *name, ...) https://github.com/ruby/ruby/blob/trunk/struct.c#L439 if (!name) st = anonymous_struct(rb_cStruct); else st = new_struct(rb_str_new2(name), rb_cStruct); - return setup_struct(st, ary, 0); + return setup_struct(st, ary); } VALUE @@ -455,7 +452,7 @@ rb_struct_define_under(VALUE outer, const char *name, ...) https://github.com/ruby/ruby/blob/trunk/struct.c#L452 ary = struct_make_members_list(ar); va_end(ar); - return setup_struct(rb_define_class_under(outer, name, rb_cStruct), ary, 0); + return setup_struct(rb_define_class_under(outer, name, rb_cStruct), ary); } /* @@ -574,7 +571,7 @@ rb_struct_s_def(int argc, VALUE *argv, VALUE klass) https://github.com/ruby/ruby/blob/trunk/struct.c#L571 else { st = new_struct(name, klass); } - setup_struct(st, rest, (int)keyword_init); + 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); diff --git a/test/ruby/test_struct.rb b/test/ruby/test_struct.rb index f13afbb..85de0f2 100644 --- a/test/ruby/test_struct.rb +++ b/test/ruby/test_struct.rb @@ -114,10 +114,9 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L114 assert_equal "#{@Struct}::KeywordInitFalse", @Struct::KeywordInitFalse.inspect assert_equal "#{@Struct}::KeywordInitTrue(keyword_init: true)", @Struct::KeywordInitTrue.inspect # eval is needed to prevent the warning duplication filter - k = eval("Class.new(@Struct::KeywordInitFalse) {def initialize(**) end}") - assert_warn(/Using the last argument as keyword parameters is deprecated/) {k.new(a: 1, b: 2)} - k = Class.new(@Struct::KeywordInitTrue) {def initialize(**) end} - assert_warn('') {k.new(a: 1, b: 2)} + k = Class.new(@Struct::KeywordInitTrue) {def initialize(b, options); super(a: options, b: b); end} + o = assert_warn('') { k.new(42, {foo: 1, bar: 2}) } + assert_equal(1, o.a[:foo]) @Struct.instance_eval do remove_const(:KeywordInitTrue) @@ -152,6 +151,17 @@ module TestStruct https://github.com/ruby/ruby/blob/trunk/test/ruby/test_struct.rb#L151 assert_equal([1, 2], o.each.to_a) end + def test_initialize_with_kw + klass = @Struct.new(:foo, :options) do + def initialize(foo, **options) + super(foo, options) + end + end + assert_equal({}, klass.new(42, **Hash.new).options) + x = assert_warn('') { klass.new(1, bar: 2) } + assert_equal 2, x.options[:bar] + end + def test_each_pair klass = @Struct.new(:a, :b) o = klass.new(1, 2) diff --git a/version.h b/version.h index 6a2a433..04dd454 100644 --- a/version.h +++ b/version.h @@ -2,7 +2,7 @@ https://github.com/ruby/ruby/blob/trunk/version.h#L2 # define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR #define RUBY_VERSION_TEENY 1 #define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR -#define RUBY_PATCHLEVEL 113 +#define RUBY_PATCHLEVEL 114 #define RUBY_RELEASE_YEAR 2020 #define RUBY_RELEASE_MONTH 7 -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/