https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112022-09-08T18:44:07ZRuby Issue Tracking SystemRuby master - 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?journal_id=990912022-09-08T18:44:07ZRubyBugs (A Nonymous)msiegel@riverdaletechinc.com
<ul></ul><p>Per <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/13">@matz (Yukihiro Matsumoto)</a> <a href="https://bugs.ruby-lang.org/issues/16122#note-51" class="external">here</a>, the preference would be for the constructor to take either:</p>
<ul>
<li>Only keyword args</li>
<li>Either keyword args OR positional args</li>
</ul>
<p>The <a href="https://github.com/ms-ati/Values" class="external">Values gem</a> provides separate positional and keyword args constructors:</p>
<ul>
<li>
<code>.new</code> -- positional constructor</li>
<li>
<code>.with</code> -- keyword args constructor</li>
</ul>
<p>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.</p>
<p>For example, when using simple immutable value objects, a keyword args constructor combined with a <code>#with</code> method to copy an instance with discrete changes (see <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Data: Add "Copy with changes method" [Follow-on to #16122 Data: simple immutable value object] (Closed)" href="https://bugs.ruby-lang.org/issues/19000">#19000</a>), can completely replace the need for default values, as follows:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Point</span> <span class="o">=</span> <span class="no">Data</span><span class="p">.</span><span class="nf">define</span><span class="p">(</span><span class="ss">:x</span><span class="p">,</span> <span class="ss">:y</span><span class="p">,</span> <span class="ss">:z</span><span class="p">)</span>
<span class="no">Default</span> <span class="o">=</span> <span class="no">Point</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">x: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">y: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">z: </span><span class="mi">3</span><span class="p">)</span>
<span class="nb">p</span> <span class="o">=</span> <span class="no">Default</span><span class="p">.</span><span class="nf">with</span><span class="p">(</span><span class="ss">x: </span><span class="mi">42</span><span class="p">)</span>
<span class="c1">#=> Point(x: 42, y: 2, z: 3)</span>
</code></pre> Ruby master - 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?journal_id=991132022-09-10T13:24:03Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p>There isn't any need for this ticket as a separate request, as far as I am concerned.<br>
It works in the initial implementation of data already as submitted in <a href="https://bugs.ruby-lang.org/issues/16122#note-68" class="external">https://bugs.ruby-lang.org/issues/16122#note-68</a>, and even works with ol' good Struct, too:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Point</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:x</span><span class="p">,</span> <span class="ss">:y</span><span class="p">,</span> <span class="ss">:z</span><span class="p">)</span>
<span class="no">Point</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">].</span><span class="nf">to_h</span><span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="no">Point</span><span class="p">[</span><span class="o">**</span><span class="n">_1</span><span class="p">]</span> <span class="p">}</span> <span class="o">==</span> <span class="no">Point</span><span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">]</span> <span class="c1"># => true</span>
</code></pre>