
Issue #19278 has been updated by zverok (Victor Shepelev). Status changed from Open to Feedback It is a deliberate and documented design decision: `new` handles unifying positional and keyword args, and `initialize` always [receives keyword args](https://docs.ruby-lang.org/en/master/Data.html#method-c-new).
Note that Measure#initialize always receives keyword arguments, and that mandatory arguments are checked in initialize, not in new. This can be important for redefining initialize in order to convert arguments or provide defaults
Check it: ```ruby class Point < Data.define(:x, :y) def initialize(*a, **kwa) puts "args: #{a}, kwargs: #{kwa}" super end end Point.new(1, 2) # args: [], kwargs: {:x=>1, :y=>2} Point.new(x: 1, y: 2) # args: [], kwargs: {:x=>1, :y=>2} ``` This decision was made for usability: this way, it is easy for class user to redefine `#initialize` with small additions (like converting argument types or providing defaults): ```ruby class Point < Data.define(:x, :y, :z) def initialize(x:, y:, z: 0) = super end p Point.new(1, 2) #=> #<data Point x=1, y=2, z=0> p Point.new(x: 1, y: 2) #=> #<data Point x=1, y=2, z=0> p Point.new(1, 2, 3) #=> #<data Point x=1, y=2, z=3> p Point.new(x: 1, y: 2, z: 3) #=> <data Point x=1, y=2, z=3> ``` Now, imagine amount of code one would need to write in `#initialize` if the difference of keyword vs positional arguments initialization would be handled there. ---------------------------------------- Bug #19278: Constructing subclasses of Data with positional arguments https://bugs.ruby-lang.org/issues/19278#change-100864 * Author: tenderlovemaking (Aaron Patterson) * Status: Feedback * Priority: Normal * ruby -v: ruby 3.2.0 (2022-12-25 revision a528908271) [arm64-darwin22] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- I'd expect both of the following subclasses to work, but the subclass that uses positional parameters raises an exception: ```ruby Foo = Data.define class Bar < Foo def initialize foo: p foo end end class Baz < Foo def initialize foo p foo end end Bar.new foo: 1 # Prints 1 Baz.new 1 # Raises ArgumentError ``` I'd expect the subclass that uses positional arguments to work. -- https://bugs.ruby-lang.org/