[ruby-core:112222] [Ruby master Bug#19416] Inconsistent behaviour for Struct.new without any member_names

Issue #19416 has been reported by herwin (Herwin W). ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/

Issue #19416 has been updated by jeremyevans0 (Jeremy Evans). I submitted a pull request to fix this: https://github.com/ruby/ruby/pull/7290. Not ready for merge yet as the debug gem's tests needs to be fixed not to use such a struct. ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416#change-101797 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/

Issue #19416 has been updated by zverok (Victor Shepelev). FWIW, `Data` consciously allows member-less definitions, intended to be a tag/case values: ```ruby class Request Success = Data.new(:body) NotFound = Data.new ``` The latter is rendered consistently with `Success`, convenient to reuse in pattern-matching, and can be expanded later when the architecture needs this. It might be that the same logic applies to memberless `Struct` to some extent (even if its intended usage is different from `Data`, consistency in such things between the two might be desirable). ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416#change-102112 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/

Issue #19416 has been updated by matz (Yukihiro Matsumoto). After consideration, I think we should allow empty `Struct` even without the name for consistency. Matz. ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416#change-102250 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/

Issue #19416 has been updated by mame (Yusuke Endoh). Just for record. What made matz change his mind was the following code I wrote. ```ruby Cons = Struct.new(:car, :cdr) Nil = Struct.new() ``` All we need to change Ruby is a simple code that shows a use case. ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416#change-102261 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/

Issue #19416 has been updated by jeremyevans0 (Jeremy Evans). matz (Yukihiro Matsumoto) wrote in #note-3:
After consideration, I think we should allow empty `Struct` even without the name for consistency.
I submitted a pull request to implement this: https://github.com/ruby/ruby/pull/7587 ---------------------------------------- Bug #19416: Inconsistent behaviour for Struct.new without any member_names https://bugs.ruby-lang.org/issues/19416#change-102515 * Author: herwin (Herwin W) * Status: Open * Priority: Normal * ruby -v: ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- When I simply declare a Struct without any arguments, I get an error: ``` irb(main):001:0> Struct.new (irb):1:in `new': wrong number of arguments (given 0, expected 1+) (ArgumentError) from (irb):1:in `<main>' ``` But Struct has an option to pass a class name as the first argument, which will create the struct as a constant in the Struct namespace. If this argument is given, there is no ArgumentError ``` irb(main):002:0> Struct.new('Foo') => Struct::Foo ``` This results in a rather pointless class ``` irb(main):003:0> Struct::Foo.new(1) (irb):3:in `initialize': struct size differs (ArgumentError) from (irb):3:in `new' irb(main):004:0> Struct::Foo.new => #<struct Struct::Foo> ``` This behaviour is not documented in the Struct class, but I would guess this is not how it is intended to be. -- https://bugs.ruby-lang.org/
participants (6)
-
herwin (Herwin W)
-
jeremyevans0 (Jeremy Evans)
-
jeremyevans0 (Jeremy Evans)
-
mame (Yusuke Endoh)
-
matz (Yukihiro Matsumoto)
-
zverok (Victor Shepelev)