Bug #16801
closed
The default Struct constructor improperly handle keyword arguments
Added by byroot (Jean Boussier) over 4 years ago.
Updated over 4 years ago.
Description
Reproduction script:
Field = Struct.new(:value) do
def initialize(value, keyword: false)
super(value)
@keyword = keyword
end
end
Field.new(1, keyword: true)
/tmp/kw.rb:8: warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call
/tmp/kw.rb:2: warning: The called method `initialize' is defined here
This can be worked around with keyword_init: true
, but I see no reason why Struct
couldn't properly handle keyword arguments in it's default constructor.
I have a patch for this: https://github.com/ruby/ruby/pull/3045 however I had to modify a test that was explicitly expecting that warning, so maybe I'm missing something.
- Tracker changed from Bug to Feature
- ruby -v deleted (
ruby 2.7.1p83)
- Backport deleted (
2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN)
I think the something your missing is this would break existing code:
Struct.new(:hash_value).new(hash_key: 1)
Treating the keywords as named columns when they were originally designed to be a hash value for the next column will definitely break existing code. That is why keyword_init
must be specified explicitly.
The current design is expected and not a bug. Switching this to a feature request.
@jeremyevans0 (Jeremy Evans) I'm afraid I don't understand what you are referring to:
2.7.1:
$ ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-darwin19]
$ ruby --disable-gems -e 'p Struct.new(:hash_value).new(hash_key: 1)'
#<struct hash_value={:hash_key=>1}>
My patch:
$ ./ruby -v
ruby 2.8.0dev (2020-04-20T09:16:19Z struct-new-keyword 08d8195ff8) [x86_64-darwin19]
$ ./ruby --disable-gems -e 'p Struct.new(:hash_value).new(hash_key: 1)'
#<struct hash_value={:hash_key=>1}>
To clarify, what I'm trying to say is that the "new"
method should simply forward everything to the initialize
method no matter what. I can't see any reason for Struct#new
to have arbitrary restrictions.
- Tracker changed from Feature to Bug
- ruby -v set to ruby 2.7.1p83
- Backport set to 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN
byroot (Jean Boussier) wrote in #note-3:
To clarify, what I'm trying to say is that the "new"
method should simply forward everything to the initialize
method no matter what. I can't see any reason for Struct#new
to have arbitrary restrictions.
Sorry about misunderstanding. Your clarification makes a lot more sense. It seems reasonable that keyword_init
would only affect #initialize
and not .new
.
- Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: REQUIRED
- Status changed from Open to Closed
- Backport changed from 2.5: DONTNEED, 2.6: DONTNEED, 2.7: REQUIRED to 2.5: DONTNEED, 2.6: DONTNEED, 2.7: DONE
ruby_2_7 61c6d433060881e952140d2154c06f8c9803dc8a.
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0