https://bugs.ruby-lang.org/
https://bugs.ruby-lang.org/favicon.ico?1711330511
2022-02-12T20:35:09Z
Ruby Issue Tracking System
Ruby master - Feature #18583: Pattern-matching: API for custom unpacking strategies?
https://bugs.ruby-lang.org/issues/18583?journal_id=96478
2022-02-12T20:35:09Z
zverok (Victor Shepelev)
zverok.offline@gmail.com
<ul></ul><p>One simpler example is, that matching something with regexps with capture groups is still quite annoying!</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">string</span>
<span class="k">when</span> <span class="sr">/{{(.+?)}}/</span>
<span class="n">content</span> <span class="o">=</span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">last_match</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="c1"># looking into global value isn't exactly elegant, right?</span>
</code></pre>
<p>We could've probably bend it towards</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">string</span>
<span class="k">in</span> <span class="sr">/{{(.+?)}}/</span> <span class="o">=></span> <span class="n">content</span> <span class="c1"># the matched group</span>
</code></pre>
<p>This, though, raises a question of several match groups, at which point one starts to want more:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">string</span>
<span class="k">in</span> <span class="sr">/{{(.+?): (.+?)}}/</span> <span class="o">=></span> <span class="p">[</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">]</span>
<span class="c1"># use key and value</span>
<span class="k">in</span> <span class="sr">/{{=(?<named>.+?)}}/</span> <span class="o">=></span> <span class="p">{</span><span class="n">named</span><span class="p">:}</span>
<span class="c1"># use named</span>
</code></pre>
<p>...so... IDK.</p>
Ruby master - Feature #18583: Pattern-matching: API for custom unpacking strategies?
https://bugs.ruby-lang.org/issues/18583?journal_id=96677
2022-02-27T03:24:33Z
hmdne (hmdne -)
<ul></ul><blockquote>
<p><code># looking into global value isn't exactly elegant, right?</code></p>
</blockquote>
<p>It's not global, it's Fiber-local, so are $1 and friends. This may not be messaged well enough in the documentation though...</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">z</span> <span class="o">=</span> <span class="no">Fiber</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="sr">/(.)/</span> <span class="o">=~</span> <span class="s1">'test'</span> <span class="p">}</span>
<span class="o">=></span> <span class="c1">#<Fiber:0x00007f698a2897e0 (pry):1 (created)></span>
<span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="n">z</span><span class="p">.</span><span class="nf">resume</span>
<span class="o">=></span> <span class="mi">0</span>
<span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span> <span class="no">Regexp</span><span class="p">.</span><span class="nf">last_match</span>
<span class="o">=></span> <span class="kp">nil</span>
<span class="p">[</span><span class="mi">4</span><span class="p">]</span> <span class="n">pry</span><span class="p">(</span><span class="n">main</span><span class="p">)</span><span class="o">></span>
</code></pre>
Ruby master - Feature #18583: Pattern-matching: API for custom unpacking strategies?
https://bugs.ruby-lang.org/issues/18583?journal_id=96900
2022-03-17T13:10:51Z
palkan (Vladimir Dementyev)
dementiev.vm@gmail.com
<ul></ul><blockquote>
<p>This, though, raises a question of several match groups, at which point one starts to want more:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">string</span>
<span class="k">in</span> <span class="sr">/{{(.+?): (.+?)}}/</span> <span class="o">=></span> <span class="p">[</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">]</span>
<span class="c1"># use key and value</span>
<span class="k">in</span> <span class="sr">/{{=(?<named>.+?)}}/</span> <span class="o">=></span> <span class="p">{</span><span class="n">named</span><span class="p">:}</span>
<span class="c1"># use named</span>
</code></pre>
<p>...so... IDK.</p>
</blockquote>
<p>This one could be achieve via guards:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">case</span> <span class="n">val</span>
<span class="k">in</span> <span class="sr">/(foo|bar)/</span> <span class="k">if</span> <span class="vg">$~</span> <span class="k">in</span> <span class="p">[</span><span class="n">val</span><span class="p">]</span>
<span class="nb">puts</span> <span class="n">val</span>
<span class="k">in</span> <span class="sr">/(?<named>\d+)/</span> <span class="k">if</span> <span class="vg">$~</span> <span class="k">in</span> <span class="p">{</span><span class="ss">named: </span><span class="p">}</span>
<span class="nb">puts</span> <span class="n">named</span>
<span class="k">end</span>
</code></pre>
<p>That would require adding MatchData#{deconstruct,deconstruct_keys}, though:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">refine</span> <span class="no">MatchData</span> <span class="k">do</span>
<span class="k">alias</span> <span class="n">deconstruct</span> <span class="n">captures</span>
<span class="k">def</span> <span class="nf">deconstruct_keys</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="n">named_captures</span><span class="p">.</span><span class="nf">transform_keys</span><span class="p">(</span><span class="o">&</span><span class="ss">:to_sym</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Regarding the original proposal (the unpacking API), I think, it could bring more confusion than value. Adding one more <em>implicit</em> layer (in addition to <code>#deconstruct</code> and <code>#deconstruct_keys</code>, which could also be overridden) would make pattern matching even more <em>magical</em> in a bad sense.</p>