Skip to content

Commit 90bfaa0

Browse files
committed
[GR-45621] Handle positional or keywords args for Struct without keyword_init: true
PullRequest: truffleruby/4141
2 parents 9aed25b + 2353ee1 commit 90bfaa0

File tree

4 files changed

+11
-5
lines changed

4 files changed

+11
-5
lines changed

Diff for: CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Compatibility:
4343
* Implement `Time#deconstruct_keys` from Ruby 3.2 (#3039, @rwstauner).
4444
* Do not autosplat a proc that accepts a single positional argument and keywords (#3039, @andrykonchin).
4545
* Support passing anonymous * and ** parameters as method call arguments (#3039, @andrykonchin).
46+
* Handle either positional or keywords arguments by default in `Struct.new` (#3039, @rwstauner).
4647

4748
Performance:
4849

Diff for: spec/tags/core/struct/initialize_tags.txt

-2
This file was deleted.

Diff for: spec/tags/core/struct/new_tags.txt

-1
This file was deleted.

Diff for: src/main/ruby/truffleruby/core/struct.rb

+10-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ def self.new(klass_name, *attrs, keyword_init: nil, &block)
5656
end
5757

5858
klass = Class.new self do
59-
_specialize attrs unless keyword_init
59+
# _specialize doesn't support keyword arguments
60+
_specialize attrs if Primitive.false?(keyword_init)
6061

6162
attrs.each do |a|
6263
define_method(a) { Primitive.object_hidden_var_get(self, a) }
@@ -71,6 +72,7 @@ def self.[](*args)
7172
new(*args)
7273
end
7374

75+
# This doesn't apply when keyword_init is nil.
7476
if keyword_init
7577
def self.inspect
7678
super + '(keyword_init: true)'
@@ -156,7 +158,13 @@ def initialize(*args, **kwargs)
156158
raise ArgumentError, "Expected #{attrs.size}, got #{args.size}"
157159
end
158160

159-
if Primitive.class(self)::KEYWORD_INIT
161+
keyword_init = Primitive.class(self)::KEYWORD_INIT
162+
163+
# When keyword_init is nil:
164+
# If there are any positional args we treat them all as positional.
165+
# If there are no args at all we also want to run the positional handling code.
166+
167+
if keyword_init || (Primitive.nil?(keyword_init) && args.empty? && !kwargs.empty?)
160168
# Accept a single positional hash for https://bugs.ruby-lang.org/issues/18632 and spec
161169
if kwargs.empty? && args.size == 1 && Primitive.is_a?(args.first, Hash)
162170
kwargs = args.first

0 commit comments

Comments
 (0)