Project

General

Profile

Actions

Bug #19416

closed

Inconsistent behaviour for Struct.new without any member_names

Added by herwin (Herwin W) over 1 year ago. Updated over 1 year ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-linux-gnu]
[ruby-core:112222]

Description

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.

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

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.

Updated by zverok (Victor Shepelev) over 1 year ago

FWIW, Data consciously allows member-less definitions, intended to be a tag/case values:

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).

Updated by matz (Yukihiro Matsumoto) over 1 year ago

After consideration, I think we should allow empty Struct even without the name for consistency.

Matz.

Updated by mame (Yusuke Endoh) over 1 year ago

Just for record. What made matz change his mind was the following code I wrote.

Cons = Struct.new(:car, :cdr)
Nil = Struct.new()

All we need to change Ruby is a simple code that shows a use case.

Updated by jeremyevans0 (Jeremy Evans) over 1 year ago

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

Actions #6

Updated by jeremyevans (Jeremy Evans) over 1 year ago

  • Status changed from Open to Closed

Applied in changeset git|f8e7048348d022814736d0a7e49f2f2494db6a2f.


Allow anonymous memberless Struct

Previously, named memberless Structs were allowed, but anonymous
memberless Structs were not.

Fixes [Bug #19416]

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0