From: "RubyBugs (A Nonymous)" Date: 2022-09-08T18:44:07+00:00 Subject: [ruby-core:109854] [Ruby master Feature#19001] Data: Add #to_h symmetric to constructor with keyword args [Follow-on to #16122 Data: simple immutable value object] Issue #19001 has been updated by RubyBugs (A Nonymous). Per @Matz [here](https://bugs.ruby-lang.org/issues/16122#note-51), the preference would be for the constructor to take either: * Only keyword args * Either keyword args OR positional args The [Values gem](https://github.com/ms-ati/Values) provides separate positional and keyword args constructors: * `.new` -- positional constructor * `.with` -- keyword args constructor Given the high need for ergonomics related to the keyword args constructor, my recommendation is that this one is more important than a positional constructor. For example, when using simple immutable value objects, a keyword args constructor combined with a `#with` method to copy an instance with discrete changes (see #19000), can completely replace the need for default values, as follows: ```ruby Point = Data.define(:x, :y, :z) Default = Point.new(x: 1, y: 2, z: 3) p = Default.with(x: 42) #=> Point(x: 42, y: 2, z: 3) ``` ---------------------------------------- Feature #19001: Data: Add #to_h symmetric to constructor with keyword args [Follow-on to #16122 Data: simple immutable value object] https://bugs.ruby-lang.org/issues/19001#change-99091 * Author: RubyBugs (A Nonymous) * Status: Open * Priority: Normal ---------------------------------------- *Extracted a follow-up to [#16122 Data: simple immutable value object](https://bugs.ruby-lang.org/issues/16122)* # Proposal: Add a `#to_h` method symmetric to a constructor accepting keyword arguments This allows round-trip between a `Hash` and a Value object instance, for example: ```ruby Point = Data.define(:x, :y, :z) points = [ Point.new(x: 1, y: 0, z: 0), Point.new(x: 0, y: 1, z: 0), Point.new(x: 0, y: 0, z: 1), ] hashes = points.map(&:to_h) points_2 = hashes.map { |h| Point.new(**h) } points_2 == points #=> true ``` ## Why? Having symmetric operation between `#to_h` and a keyword-args constructor is a major ergonomic factor in usage of immutable value objects. To play with code that works like this, you may take a look at the [Values gem](https://rubygems.org/gems/values) ## Alternatives If there is no symmetric construction and de-construction along these lines, a number of use cases become more complicated and less ergonomic. -- https://bugs.ruby-lang.org/ Unsubscribe: