From: "zverok (Victor Shepelev) via ruby-core" Date: 2022-12-29T22:34:07+00:00 Subject: [ruby-core:111516] [Ruby master Bug#19278] Constructing subclasses of Data with positional arguments Issue #19278 has been updated by zverok (Victor Shepelev). @sam.saffron your hand-maid `Foo` is analogous to `Foo = Data.define(:x)`, right? Now, can you please show what if somebody wants to inherit your `Foo` to provide: * argument conversion for `x` * or, default value for `x` I believe, the best you can get with would be something like this, for data conversion: ```ruby UNDEFINED = Object.new.freeze class MyFoo < Foo def initialize(pos_x = UNDEFINED, x: UNDEFINED) # 1. check that one, and exactly of them is `UNDEFINED` # 2. do the conversion with the right one, we'd like to preserve the protocol, right?.. if pos_x == UNDEFINED super(x: x.to_i) else super(pos_x.to_i) end end end ``` Providing the default value, how would you address this?.. Please share your thoughts! With the current protocol, it is just like that: ```ruby # Conversion Foo = Data.define(:x) do def initialize(x:) = super(x: x.to_i) end # Default value: Foo = Data.define(:x) do def initialize(x: 0) = super end # Both with now work with Foo.new(1) and Foo.new(x: 1), without breaking the contract that Data promises ``` Yes, the rule "`Data#initialize` accepts only keyword arguments" is unlike the barest "simple class" implementation, but: 1. For a good reason 2. It is a rule consisting of _exactly one phrase_; even if one considers it "a dumb quirk," it is not something that is impossible to explain or remember 3. But it is not "a dumb quirk" ---------------------------------------- Bug #19278: Constructing subclasses of Data with positional arguments https://bugs.ruby-lang.org/issues/19278#change-100884 * 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/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/postorius/lists/ruby-core.ml.ruby-lang.org/