https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112019-01-11T19:57:47ZRuby Issue Tracking SystemRuby master - Feature #15526: New way to destruct an object hashhttps://bugs.ruby-lang.org/issues/15526?journal_id=762512019-01-11T19:57:47Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><p>Not exactly what you are describing, but, funny enough, there is a way!</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">config</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">host: </span><span class="s1">'localhost'</span><span class="p">,</span> <span class="ss">port: </span><span class="mi">3000</span> <span class="p">}</span>
<span class="n">config</span><span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="o">|</span><span class="n">host</span><span class="p">:,</span> <span class="n">port</span><span class="ss">:|</span>
<span class="nb">p</span> <span class="s2">"host=</span><span class="si">#{</span><span class="n">host</span><span class="si">}</span><span class="s2">, port=</span><span class="si">#{</span><span class="n">port</span><span class="si">}</span><span class="s2">"</span>
<span class="p">}</span>
</code></pre> Ruby master - Feature #15526: New way to destruct an object hashhttps://bugs.ruby-lang.org/issues/15526?journal_id=762522019-01-11T20:15:24Zshevegen (Robert A. Heiler)shevegen@gmail.com
<ul></ul><blockquote>
<p>What do you guys think?</p>
</blockquote>
<p>Ultimately you only have to convince matz, so the rest is just people giving opinions. :)</p>
<p>Victor wrote:</p>
<blockquote>
<p>Not exactly what you are describing, but, funny enough, there is a way!</p>
</blockquote>
<pre><code>config.then { |host:, port:|
</code></pre>
<p>Admit it, you only wanted to use <strong>.then</strong>. ;)</p>
<p>To the original suggestion:</p>
<pre><code>{ host, port } = config
</code></pre>
<p>Personally I am not a huge fan of the syntax proposal simply due to<br>
the {} part. My brain tends to associate this as a Hash, so I get confused<br>
when the {} is on the left side. {} already has quite some meanings, e. g.<br>
do/end. I would rather prefer to keep any meaning of {} smaller rather<br>
than expand on it.</p>
<p>Syntax aside, I am not sure I like the proposal as such either, but I don't<br>
care that much really. My opinion is slightly against it but it's not that<br>
strong.</p>
<blockquote>
<p>I know Ruby has Hash#values_at, but I think this way it's more readable<br>
and understandable</p>
</blockquote>
<p>I prefer .values_at since I like object.method notation in general, unless<br>
there is a significantly shorter and readable way that does not cause<br>
that much confusion. But I think this is difficult to agree because what<br>
may be readable or easy to understand for one person, may be difficult<br>
to understand for someone else.</p>
<p>Actually, although I myself still am not using yield_self/then, I'd rather<br>
prefer the variant shown by Victor, rather than the { } variant on the<br>
left hand side, but that may be just my own personal opinion.</p>
<p>If you feel strongly about your proposal you could consider adding your<br>
proposal to any upcoming developer meeting.</p> Ruby master - Feature #15526: New way to destruct an object hashhttps://bugs.ruby-lang.org/issues/15526?journal_id=762532019-01-11T20:35:21Zzverok (Victor Shepelev)zverok.offline@gmail.com
<ul></ul><blockquote>
<p>Admit it, you only wanted to use <code>.then</code></p>
</blockquote>
<p>That's absolutely not the point. The real point here is:</p>
<ol>
<li>
<p>Ruby has very consistent "argument <strong>deconstruction</strong>" rules. Basically, "it is deconstructed the same way it is constructed", e.g., if you can <em>call</em> (construct) with arguments like <code>meth(a, *b, c: 1, d: 2, **e)</code>, you can also <em>receive</em> (deconstruct) arguments exactly the same way: <code>a, *b, c:, d: nil, **e</code>.</p>
</li>
<li>
<p>The deconstruction is fully enabled in arguments (including keyword arguments) to procs and methods</p>
</li>
<li>
<p>Initially (before keyword arguments), the variable assignment had the same "expressive power", e.g. you could define a method like</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">meth</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span><span class="p">)</span>
</code></pre>
<p>...and you could assign variables the same way:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
</code></pre>
<ol start="4">
<li>When keyword arguments were introduced, there was no matching syntax for variable assignment. If it <strong>would</strong> exist, it most probably <strong>should</strong> look this way (same as arguments, remember):</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">:,</span> <span class="n">b</span><span class="p">:,</span> <span class="o">**</span><span class="n">kwrest</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">,</span> <span class="ss">d: </span><span class="mi">4</span><span class="p">}</span>
</code></pre>
<p>It obviously looks confusing (and would probably be hard for the parser), and I believe that's the reason it was NOT added to the language.</p>
<ol start="5">
<li>
<p>I don't think adding "orphan feature" (looking like nothing else in the language) just for the sake of this particular case would be ever accepted; and I don't think it should.</p>
</li>
<li>
<p>In the meantime, "chainable" code style (with <code>Enumerable</code> and <code>#then</code>) allows to embrace argument deconstruction in its full force:</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">config</span><span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="o">|</span><span class="n">host</span><span class="p">:,</span> <span class="ss">port: </span><span class="mi">8080</span><span class="p">,</span> <span class="o">**</span><span class="n">rest</span><span class="o">|</span>
</code></pre>
<p>...which is NOT the main (and obviously not the only) reason to use this style, just a nice side-effect of its consistency with the rest of the language.</p> Ruby master - Feature #15526: New way to destruct an object hashhttps://bugs.ruby-lang.org/issues/15526?journal_id=762672019-01-12T15:04:59Zjanfri (Jan Friedrich)janfri26@gmail.com
<ul></ul><p>zverok (Victor Shepelev) wrote:</p>
<blockquote>
<ol>
<li>
<p>Ruby has very consistent "argument <strong>deconstruction</strong>" rules. Basically, "it is deconstructed the same way it is constructed", e.g., if you can <em>call</em> (construct) with arguments like <code>meth(a, *b, c: 1, d: 2, **e)</code>, you can also <em>receive</em> (deconstruct) arguments exactly the same way: <code>a, *b, c:, d: nil, **e</code>.</p>
</li>
<li>
<p>The deconstruction is fully enabled in arguments (including keyword arguments) to procs and methods</p>
</li>
<li>
<p>Initially (before keyword arguments), the variable assignment had the same "expressive power", e.g. you could define a method like</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">meth</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span><span class="p">)</span>
</code></pre>
<p>...and you could assign variables the same way:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="o">*</span><span class="n">rest</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
</code></pre>
<ol start="4">
<li>When keyword arguments were introduced, there was no matching syntax for variable assignment. If it <strong>would</strong> exist, it most probably <strong>should</strong> look this way (same as arguments, remember):</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">:,</span> <span class="n">b</span><span class="p">:,</span> <span class="o">**</span><span class="n">kwrest</span> <span class="o">=</span> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">,</span> <span class="ss">d: </span><span class="mi">4</span><span class="p">}</span>
</code></pre>
<p>It obviously looks confusing (and would probably be hard for the parser), and I believe that's the reason it was NOT added to the language.</p>
<ol start="5">
<li>
<p>I don't think adding "orphan feature" (looking like nothing else in the language) just for the sake of this particular case would be ever accepted; and I don't think it should.</p>
</li>
<li>
<p>In the meantime, "chainable" code style (with <code>Enumerable</code> and <code>#then</code>) allows to embrace argument deconstruction in its full force:</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">config</span><span class="p">.</span><span class="nf">then</span> <span class="p">{</span> <span class="o">|</span><span class="n">host</span><span class="p">:,</span> <span class="ss">port: </span><span class="mi">8080</span><span class="p">,</span> <span class="o">**</span><span class="n">rest</span><span class="o">|</span>
</code></pre>
<p>...which is NOT the main (and obviously not the only) reason to use this style, just a nice side-effect of its consistency with the rest of the language.</p>
</blockquote>
<p>+1 Great analysis.</p> Ruby master - Feature #15526: New way to destruct an object hashhttps://bugs.ruby-lang.org/issues/15526?journal_id=763112019-01-14T15:45:52Zelia (Elia Schito)elia@schito.me
<ul></ul><p>Related/duplicate <a href="https://bugs.ruby-lang.org/issues/11758" class="external">https://bugs.ruby-lang.org/issues/11758</a></p>