1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

Initialize Struct by calling with keyword arguments

This commit is contained in:
Nobuyoshi Nakada 2021-12-26 22:39:48 +09:00
parent abad017354
commit c956f979e5
No known key found for this signature in database
GPG key ID: 7CD2805BFA3770C6
Notes: git 2021-12-27 00:34:22 +09:00
2 changed files with 18 additions and 10 deletions

View file

@ -685,12 +685,25 @@ rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self)
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)
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]);
}

View file

@ -362,9 +362,8 @@ module TestStruct
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) }