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:
parent
abad017354
commit
c956f979e5
Notes:
git
2021-12-27 00:34:22 +09:00
2 changed files with 18 additions and 10 deletions
23
struct.c
23
struct.c
|
@ -685,12 +685,25 @@ rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE keyword_init = rb_struct_s_keyword_init(klass);
|
bool keyword_init = false;
|
||||||
if (RTEST(keyword_init)) {
|
switch (rb_struct_s_keyword_init(klass)) {
|
||||||
struct struct_hash_set_arg arg;
|
default:
|
||||||
if (argc > 1 || !RB_TYPE_P(argv[0], T_HASH)) {
|
if (argc > 1 || !RB_TYPE_P(argv[0], T_HASH)) {
|
||||||
rb_raise(rb_eArgError, "wrong number of arguments (given %d, expected 0)", argc);
|
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);
|
rb_mem_clear((VALUE *)RSTRUCT_CONST_PTR(self), n);
|
||||||
arg.self = self;
|
arg.self = self;
|
||||||
arg.unknown_keywords = Qnil;
|
arg.unknown_keywords = Qnil;
|
||||||
|
@ -704,10 +717,6 @@ rb_struct_initialize_m(int argc, const VALUE *argv, VALUE self)
|
||||||
if (n < argc) {
|
if (n < argc) {
|
||||||
rb_raise(rb_eArgError, "struct size differs");
|
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++) {
|
for (long i=0; i<argc; i++) {
|
||||||
RSTRUCT_SET(self, i, argv[i]);
|
RSTRUCT_SET(self, i, argv[i]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -362,9 +362,8 @@ module TestStruct
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_keyword_args_warning
|
def test_keyword_args_warning
|
||||||
warning = /warning: Passing only keyword arguments to Struct#initialize will behave differently from Ruby 3\.2\./
|
assert_warn('') { assert_equal(1, @Struct.new(:a).new(a: 1).a) }
|
||||||
assert_warn(warning) { assert_equal({a: 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(warning) { assert_equal({a: 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).new({a: 1}).a) }
|
||||||
assert_warn('') { assert_equal({a: 1}, @Struct.new(:a, :b).new(1, a: 1).b) }
|
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) }
|
assert_warn('') { assert_equal(1, @Struct.new(:a, keyword_init: true).new(a: 1).a) }
|
||||||
|
|
Loading…
Add table
Reference in a new issue