From: "Eregon (Benoit Daloze)" Date: 2022-03-14T16:03:20+00:00 Subject: [ruby-core:107895] [Ruby master Bug#18632] Struct.new wrongly treats a positional Hash as keyword arguments Issue #18632 has been updated by Eregon (Benoit Daloze). And another maybe related issue, this time in Struct#new: ``` $ ruby -we 'p Struct.new(:name, :legs, keyword_init: true).new(name: "elefant", legs: 4)' # ^ OK $ ruby -we 'p Struct.new(:name, :legs, keyword_init: true).new(4)' -e:1:in `initialize': wrong number of arguments (given 1, expected 0) (ArgumentError) from -e:1:in `new' from -e:1:in `
' ^ fails as expected $ ruby -we 'p Struct.new(:name, :legs, keyword_init: true).new({name: "elefant", legs: 4})' # ^ should fail, it is not kwargs ``` And this example also show that providing `keyword_init: true` can cause an inconsistency: ``` I'm using master here to simplify: $ ruby -we 'p Struct.new(:name, :legs, keyword_init: true).new({name: "elefant", legs: 4})' # ^ incorrect $ ruby -we 'p Struct.new(:name, :legs).new({name: "elefant", legs: 4})' #"elefant", :legs=>4}, legs=nil> ^ correct $ ruby -we 'p Struct.new(:name, :legs).new(name: "elefant", legs: 4)' # ^ correct ``` ---------------------------------------- Bug #18632: Struct.new wrongly treats a positional Hash as keyword arguments https://bugs.ruby-lang.org/issues/18632#change-96834 * Author: Eregon (Benoit Daloze) * Status: Open * Priority: Normal * ruby -v: ruby 3.0.2p107 (2021-07-07 revision 0db68f0233) [x86_64-linux] * Backport: 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- ``` $ ruby -e 'Struct.new(:a, name: "b")' -e:1:in `new': unknown keyword: :name (ArgumentError) from -e:1:in `
' ^ expected $ ruby -e 'Struct.new(:a, { name: "b" })' -e:1:in `new': unknown keyword: :name (ArgumentError) from -e:1:in `
' ^ wrong ``` It shouldn't be such an error for the 2nd command since it's a positional Hash. It should be a TypeError, like when passing e.g. `nil` instead of the positional Hash. Also: ``` $ ruby -e 'p Struct.new(:a, {}).members' [:a] ``` But it should be an error to pass a positional Hash. I think this is worth fixing, because it basically breaks the separation of positional and keyword arguments for this method. Also Struct.new does take a keyword argument, `keyword_init: true`. -- https://bugs.ruby-lang.org/ Unsubscribe: