https://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112019-05-05T18:35:44ZRuby Issue Tracking SystemRuby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779232019-05-05T18:35:44Zfoonlyboy (Eike Dierks)
<ul></ul><pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">then_if</span><span class="p">(</span><span class="n">condition</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">if</span> <span class="n">condition</span>
<span class="nb">self</span><span class="p">.</span><span class="nf">then</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">else</span>
<span class="nb">self</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779242019-05-05T18:48:28Zfoonlyboy (Eike Dierks)
<ul></ul><p>A (somehow contrived) example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><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><span class="mi">5</span><span class="p">].</span><span class="nf">map</span><span class="p">{</span><span class="o">|</span><span class="n">n</span><span class="o">|</span> <span class="n">n</span><span class="p">.</span><span class="nf">then_if</span><span class="p">(</span><span class="n">n</span><span class="p">.</span><span class="nf">even?</span><span class="p">){</span><span class="s1">'even'</span><span class="p">}}</span>
<span class="o">=></span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="s2">"even"</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="s2">"even"</span><span class="p">,</span> <span class="mi">5</span><span class="p">]</span>
</code></pre> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779262019-05-05T20:30:37Zfoonlyboy (Eike Dierks)
<ul></ul><p>A more complex example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">scope</span> <span class="ss">:blacklisted_at</span><span class="p">,</span> <span class="o">-></span> <span class="p">(</span><span class="n">seller</span><span class="o">=</span><span class="kp">nil</span><span class="p">,</span> <span class="n">flag</span><span class="o">=</span><span class="kp">true</span><span class="p">)</span> <span class="p">{</span>
<span class="n">then_if</span><span class="p">(</span><span class="o">!</span> <span class="n">flag</span><span class="p">.</span><span class="nf">nil?</span><span class="p">)</span> <span class="p">{</span>
<span class="n">joins</span><span class="p">(</span><span class="ss">:disk_seller_maps</span><span class="p">)</span>
<span class="p">.</span><span class="nf">then_if</span><span class="p">(</span><span class="n">seller</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">q</span><span class="o">|</span>
<span class="n">q</span><span class="p">.</span><span class="nf">where</span><span class="p">(</span><span class="n">disk_seller_map</span><span class="p">:{</span><span class="n">seller_id</span><span class="ss">:seller</span><span class="p">})</span>
<span class="p">}</span>
<span class="p">.</span><span class="nf">then_if</span><span class="p">(</span><span class="o">!</span> <span class="n">flag</span><span class="p">)</span> <span class="p">{</span><span class="o">|</span><span class="n">q</span><span class="o">|</span>
<span class="n">all</span><span class="p">.</span><span class="nf">where</span><span class="p">.</span><span class="nf">not</span><span class="p">(</span><span class="ss">id: </span><span class="n">q</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<p>Not really sure if this does what I mean,<br>
but it looks a lot more concise now.</p>
<p>Before that all that cases would have expanded to 6 cases,<br>
but now it looks a lot more concise.</p>
<ul>
<li>
<code>then_if(! flag.nil?)</code> shields from <code>flag.nil?</code>
</li>
<li>
<code>then_if(seller)</code> only applies if a <code>seller</code> was given</li>
<li>
<code>then_if(! flag)</code> negates the <code>query</code>
</li>
</ul>
<p>This brings the code down from 2x3=6 variants,<br>
to only two code blocks (the second one being trivial in this case)</p> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779272019-05-05T20:51:10Zsawa (Tsuyoshi Sawada)
<ul></ul><p>Related to <a href="https://bugs.ruby-lang.org/issues/15557" class="external">https://bugs.ruby-lang.org/issues/15557</a>.</p> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779792019-05-11T07:13:00Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/77979/diff?detail_id=51779">diff</a>)</li></ul><p>As it seems useful only when <code>condition</code> doesn't use the parameter <code>query</code>, it is questionable to me if it is generic enough to be a language feature.</p> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=779802019-05-11T12:11:16Zsawa (Tsuyoshi Sawada)
<ul></ul><p>I have exactly the same concern as nobu. And that problem stems from the fact that, in this proposal, the condition is given as an argument of the method, which means that it has to be evaluated independently of the return value that appears in the middle of the method chain.</p>
<p>That should take us back to <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: A new class that stores a condition and the previous receiver (Open)" href="https://bugs.ruby-lang.org/issues/15557">#15557</a>, where the condition is proposed to be given as a block (or a proc, following a suggestion by nobu).</p> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=801582019-07-29T06:58:41Zko1 (Koichi Sasada)
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Rejected</i></li></ul><p>It seems difficult to introduce.</p>
<p>if you are interest about this ticket yet, could you reopen it and file on our dev-meeting agenda?<br>
<a href="https://bugs.ruby-lang.org/issues/15996" class="external">https://bugs.ruby-lang.org/issues/15996</a></p>
<p>Thanks.</p> Ruby master - Feature #15829: Object#then_if(condition){}https://bugs.ruby-lang.org/issues/15829?journal_id=831372019-12-15T08:22:37Zokuramasafumi (Masafumi OKURA)
<ul></ul><p>How about <code>call</code>ing a condition object if it's callable instead of simply using value as a condition?</p>
<pre><code>class Object
def then_if(condition, &block)
if condition
if (condition.respond_to?(:call) && condition.call(self)) || condition
self.then(&block)
end
else
self
end
end
end
</code></pre>
<p>Then we can do something like this:</p>
<pre><code>'str'.then_if(Proc.new {|str| str.downcase == str}) {|str| str.upcase}
</code></pre>
<p>I know it's complicated and not beautiful, but it's an idea anyway.</p>