From: "zverok (Victor Shepelev) via ruby-core" Date: 2022-12-29T13:13:47+00:00 Subject: [ruby-core:111505] [Ruby master Bug#19280] Wrong error message about arity of Data::define.new Issue #19280 has been updated by zverok (Victor Shepelev). Status changed from Open to Closed The report about arity is correct. `Data` decouples `.new` and `#initialize` this way: * `.new` accepts positional and keyword args, and converts positional to keyword, and passes them to `#initialize` * `#initialize` accepts only keyword arguments, and is easy to redefine for custom processing; the default implementation has all keyword arguments mandatory. If `.new` method would be implemented in Ruby, for `Data.define(:a, :b)` it'll look this way: ```ruby KEYS = [:a, :b] def self.new(*args, **kwargs) # raise if both args and kwargs provided # handle args if args.any? raise ArgumentError if args.size > KEYS.size kwargs = args.zip(KEYS).to_h { |value, name| [name, value] } end allocate.initialize(**kwargs) end ``` It other words: * for `.new`, any number of positional args is correct, as long as it has names for them * they are converted to keyword args, and passed to initialize * ...which will raise if something is missing in the default implementation, but this implementation can be redefined **without `.new` thinking about it** Consider this: ```ruby Data.define(:a, :b) do def initialize(a:, b: 0) = super end.new(1) #=> # ``` Or even this: ```ruby Data.define(:a, :b) do def initialize(a: 0, b: 0) = super end.new #=> # ``` ...so, yeah, for `new`, the message "it expects 0 to 2 args" corresponds to reality. ---------------------------------------- Bug #19280: Wrong error message about arity of Data::define.new https://bugs.ruby-lang.org/issues/19280#change-100871 * Author: kyanagi (Kouhei Yanagita) * Status: Closed * Priority: Normal * ruby -v: ruby 3.3.0dev (2022-12-28T16:43:05Z master cada537040) [x86_64-linux] * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN, 3.2: UNKNOWN ---------------------------------------- ``` $ ~/work/r/bin/ruby -e 'Data.define(:a, :b).new(1, 2, 3)' -e:1:in `new': wrong number of arguments (given 3, expected 0..2) (ArgumentError) Data.define(:a, :b).new(1, 2, 3) ^^^^^^^ from -e:1:in `
' ``` On this message, "expected 2" is appropriate because fewer arguments are not allowed. ``` $ ~/work/r/bin/ruby -e 'Data.define(:a, :b).new(1)' -e:1:in `initialize': missing keyword: :b (ArgumentError) Data.define(:a, :b).new(1) ^ from -e:1:in `new' from -e:1:in `
' ``` -- 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/