Skip to content

Commit

Permalink
[GR-45621] Handle positional or keywords args for Struct without keyw…
Browse files Browse the repository at this point in the history
…ord_init: true

PullRequest: truffleruby/4141
  • Loading branch information
andrykonchin committed Jan 31, 2024
2 parents 9aed25b + 2353ee1 commit 90bfaa0
Show file tree
Hide file tree
Showing 4 changed files with 11 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Compatibility:
* Implement `Time#deconstruct_keys` from Ruby 3.2 (#3039, @rwstauner).
* Do not autosplat a proc that accepts a single positional argument and keywords (#3039, @andrykonchin).
* Support passing anonymous * and ** parameters as method call arguments (#3039, @andrykonchin).
* Handle either positional or keywords arguments by default in `Struct.new` (#3039, @rwstauner).

Performance:

Expand Down
2 changes: 0 additions & 2 deletions spec/tags/core/struct/initialize_tags.txt

This file was deleted.

1 change: 0 additions & 1 deletion spec/tags/core/struct/new_tags.txt

This file was deleted.

12 changes: 10 additions & 2 deletions src/main/ruby/truffleruby/core/struct.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ def self.new(klass_name, *attrs, keyword_init: nil, &block)
end

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

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

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

if Primitive.class(self)::KEYWORD_INIT
keyword_init = Primitive.class(self)::KEYWORD_INIT

# When keyword_init is nil:
# If there are any positional args we treat them all as positional.
# If there are no args at all we also want to run the positional handling code.

if keyword_init || (Primitive.nil?(keyword_init) && args.empty? && !kwargs.empty?)
# Accept a single positional hash for https://bugs.ruby-lang.org/issues/18632 and spec
if kwargs.empty? && args.size == 1 && Primitive.is_a?(args.first, Hash)
kwargs = args.first
Expand Down

0 comments on commit 90bfaa0

Please sign in to comment.