Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112023-01-03T14:00:26ZRuby Issue Tracking System
Redmine Ruby master - Misc #19304 (Open): Kernel vs Object documentationhttps://bugs.ruby-lang.org/issues/193042023-01-03T14:00:26Zzverok (Victor Shepelev)zverok.offline@gmail.com
<p>The restating of the problems raised in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Move public methods from Kernel to Object (Rejected)" href="https://bugs.ruby-lang.org/issues/19300">#19300</a>, from scratch.</p>
<p>I believe it is rather a topic of <strong>community significance</strong> and would be happy if it is possible to <strong>discuss on dev-meeting</strong>, even if the outcome would probably "let's change RDoc in this or that way".</p>
<p>So, the problem statement:</p>
<ol>
<li>
<code>Kernel</code> module defines two "types" of methods: private ones, that pretend to be global (like <code>puts</code>), but actually available from inside every object; and public ones (like <code>#class</code> or <code>#frozen?</code>) that are present in every object including <code>Kernel</code>.</li>
<li>Since the beginning of times, docs provided an illusion that the second type of the methods belongs to <code>Object</code> class, which is, in fact, devoid of its own definitions, just includes <code>Kernel</code>. This was handled by special RDoc hack (which, basically, forcefully <a href="https://github.com/ruby/rdoc/blob/017bb9fa496ee0e0959facba694a053008d1ecb0/lib/rdoc/parser/c.rb#L477" class="external">reattached definition</a> of public methods if they are defined in <code>Kernel</code>, to <code>Object</code>)</li>
<li>The RDoc hack was working in C code only, so after introduction of <code>kernel.rb</code> the illusion started to crumble: methods like <code>#tap</code>, <code>#then</code>, <code>#class</code> <a href="https://docs.ruby-lang.org/en/3.2/Kernel.html" class="external">are now documented</a> as belonging to <code>Kernel</code> (breaking the tradition of public methods being documented in <code>Object</code>)</li>
<li>This is all inconsistent and confusing, and I believe, adds to friction both for newcomers and curious investigators of the language!</li>
</ol>
<p>Additionally, I believe:</p>
<ol>
<li>That the distinction of "two kinds of methods" is useful (saying from a practical experience with explaining Ruby while mentoring, writing articles, and discussing with colleagues)</li>
<li>But, considering everything, I agree with what <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/772">@Eregon (Benoit Daloze)</a> and <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/4">@nobu (Nobuyoshi Nakada)</a> say in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Move public methods from Kernel to Object (Rejected)" href="https://bugs.ruby-lang.org/issues/19300">#19300</a>: pretending that methods belong not to the module they really belong to is not the optimal way to document things!</li>
</ol>
<p>So, the options I see (save for "do nothing and let things sort themselves somehow"):</p>
<ol>
<li>Change Ruby's implementation so public methods would really belong to <code>Object</code>. Actually, I don't believe anybody would agree to experiment on this scale, so just listing it here for completeness.</li>
<li>Just remove the RDoc hack; all methods would belong to <code>Kernel</code>, and maybe some introductory free-form text will instruct that they are different. <strong>Pro:</strong> Easy to do. <strong>Contra:</strong> The <code>Kernel</code> docs would be super-confusing.</li>
<li>Continue to maintain the hack in RDoc and extend it to <code>kernel.rb</code> (so methods like <code>#clone</code> and <code>#frozen?</code> would be still in <code>Object</code>). <strong>Pro:</strong> Relatively easy to do, will maintain structure many people used to. <strong>Contra:</strong> This is still a lie, methods belong to <code>Kernel</code>, not <code>Object</code>.</li>
<li>Adjust RDoc to a) be able to separately list <strong>public</strong> and <strong>private</strong> methods in two different lists, and add intro for <code>Kernel</code> explaining how to treat those. <strong>Pro:</strong> Probably the best correspondence to reality? <strong>Contra:</strong> Not sure how easy it is to change RDoc this way; and other renderers (like ruby-doc.com and rubyapi.org) would need to adjust themselves.</li>
</ol>
<p>So far, (4) looks the most reasonable (if (1) is 100% impossible, that is!)</p> Ruby master - Feature #19059 (Open): Introduce top level `module TimeoutError` for aggregating va...https://bugs.ruby-lang.org/issues/190592022-10-15T03:04:07Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p>This proposal was originally part of <a href="https://bugs.ruby-lang.org/issues/18630" class="external">https://bugs.ruby-lang.org/issues/18630</a> but was removed because we could not decide on the name.</p>
<p>Introduce the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">TimeoutError</span>
<span class="k">end</span>
<span class="no">IO</span><span class="o">::</span><span class="no">TimeoutError</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
<span class="no">Regexp</span><span class="o">::</span><span class="no">TimeoutError</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
<span class="c1"># Maybe?</span>
<span class="no">Timeout</span><span class="o">::</span><span class="no">Error</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
</code></pre>
<p>It may be easier for users.</p>
<p>This was discussed before with the following conclusion:</p>
<ul>
<li>Top level <code>TimeoutError</code> is available.</li>
<li>Using a module for a <code>TimeoutError</code> may not be consistent with other top level <code>class #{thing}Error</code>.</li>
</ul> Ruby master - Feature #17849 (Open): Fix Timeout.timeout so that it can be used in threaded Web s...https://bugs.ruby-lang.org/issues/178492021-05-05T01:41:09Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>Making this a separate issue from <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add support for Regexp timeouts (Closed)" href="https://bugs.ruby-lang.org/issues/17837">#17837</a></p>
<p>Eregon (Benoit Daloze) wrote in <a href="https://bugs.ruby-lang.org/issues/17837#note-10" class="external">https://bugs.ruby-lang.org/issues/17837#note-10</a> (which is about timeouts for regular expressions):</p>
<blockquote>
<p>I think fixing Timeout.timeout might be possible.<br>
The main/major issue is it can trigger within <code>ensure</code>, right? Is there anything else?<br>
We could automatically mask <code>Thread#raise</code> within <code>ensure</code> so it only happens after the <code>ensure</code> body completes.<br>
And we could still have a larger "hard timeout" if an <code>ensure</code> takes way too long (shouldn't happen, but one cannot be sure).<br>
I recall discussing this with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/6346">@schneems (Richard Schneeman)</a> some time ago on Twitter.</p>
</blockquote> Ruby master - Feature #17830 (Open): Add Integer#previous and Integer#prev https://bugs.ruby-lang.org/issues/178302021-04-26T17:27:05Zrafasoares (Rafael Soares)rafasoaresms@gmail.com
<p>I think <code>Integer#pred</code> is great as the inverse of <code>#succ</code>, but it reads a bit weird as the inverse of <code>#next</code>, which might be preferable for those going for a more "reads like English" approach.</p>
<p>On that note, <code>#previous</code> reads better, but it's also twice as long as <code>#pred</code> (or even <code>#next</code>). Which is why I've also added the shorthand <code>#prev</code></p>
<p>Since Ruby strives for readability, I always thought it was weird that the team omitted this improvement.</p>
<p>Also, I thought about writing a gem for this, but:</p>
<ol>
<li>Do we really want to add another gem for such a simple change to every project?</li>
<li>Monkey-patching gems feel dirty.</li>
</ol>
<p>Finally, I want to mention that I tried looking for previous discussions on this topic, as it seems likely someone would've brought this up at some point, but was unsuccessful. Probably due to the massive amount of baggage in the core issue tracker and mailing lists, I could've missed something among the noise.</p>
<p>I've created a fork on GitHub (<a href="https://github.com/rafasoares/ruby/commit/05119848b1f480db2e809f964528799030cc7ebb" class="external">https://github.com/rafasoares/ruby/commit/05119848b1f480db2e809f964528799030cc7ebb</a>) in order to open a PR, but decided to open this ticket as well, after reading the contributing guide more carefully.</p> Ruby master - Feature #17785 (Open): Allow named parameters to be keywordshttps://bugs.ruby-lang.org/issues/177852021-04-08T15:08:40Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>We should allow named parameters to be keywords and use add a trailing <code>_</code> to the corresponding variable:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="k">class</span><span class="p">:)</span>
<span class="n">arg</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="n">class_</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">check</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="ss">class: </span><span class="no">Integer</span><span class="p">)</span> <span class="c1"># => true</span>
</code></pre>
<p>Currently, if we want such an API we have to use <code>**rest</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="o">**</span><span class="n">rest</span><span class="p">)</span>
<span class="n">class_</span> <span class="o">=</span> <span class="n">rest</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="ss">:class</span><span class="p">)</span> <span class="p">{</span> <span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">(</span><span class="s1">'missing keyword: :class'</span><span class="p">)}</span>
<span class="k">if</span> <span class="n">rest</span><span class="p">.</span><span class="nf">size</span> <span class="o">></span> <span class="mi">1</span>
<span class="n">unknown</span> <span class="o">=</span> <span class="n">rest</span><span class="p">.</span><span class="nf">keys</span> <span class="o">-</span> <span class="p">[</span><span class="ss">:class</span><span class="p">]</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">(</span><span class="s2">"unknown keyword(s): :</span><span class="si">#{</span><span class="n">unknown</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s1">', :'</span><span class="p">)</span><span class="si">}</span><span class="s2">)
end
arg.is_a?(class_)
end
</span></code></pre>
<p>This is very verbose, much less convenient, much less readable, prevents <code>steep</code> from generating the proper signature, etc.</p>
<p>We should do the same for pattern match.</p> Ruby master - Feature #17291 (Assigned): Optimize __send__ callhttps://bugs.ruby-lang.org/issues/172912020-10-29T03:05:45Zmrkn (Kenta Murata)muraken@gmail.com
<p>I made a patch to optimize a <code>__send__</code> call. This optimization replaces a <code>__send__</code> method call with a call of the method whose name is the first argument of <code>__send__</code> method. The patch is available in <a href="https://github.com/ruby/ruby/pull/3720" class="external">this pull-request</a>.</p>
<p>By this change, the redefined <code>__send__</code> method is no longer called when it is called by a symbol method name. I guess it is no problem because the following warning message is displayed for a long time.</p>
<pre><code>$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
</code></pre>
<p>This proposal introduces two new instructions: <code>sendsym</code> and <code>opt_sendsym_without_block</code>. These instructions handle the cases that the first argument of <code>__send__</code> method is not a symbol literal. I think I can combine these two instructions into one if prefered.</p>
<p>This proposal includes the change proposed in <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Optimize __send__ call with a literal method name (Open)" href="https://bugs.ruby-lang.org/issues/17288">#17288</a>. I'll mark it as a duplicate of this proposal.</p>
<p>I don't handle <code>send</code> method in this proposal. The reason is that we need to examine the redefinition of <code>send</code> method in the instruction execution time. I want to discuss only <code>__send__</code> method in this ticket.</p>
<p>The benchmark result is below:</p>
<pre><code># Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:----------------|-----------:|---------:|
|vm_send_sym | 18.001M| 112.208M|
| | -| 6.23x|
|vm_send_var | 17.779M| 30.922M|
| | -| 1.74x|
|vm_send_var_alt | 3.817M| 6.817M|
| | -| 1.79x|
</code></pre> Ruby master - Feature #17288 (Open): Optimize __send__ call with a literal method namehttps://bugs.ruby-lang.org/issues/172882020-10-27T08:32:40Zmrkn (Kenta Murata)muraken@gmail.com
<p>I made a patch to optimize a <code>__send__</code> call with a literal method name. This optimization replaces a <code>__send__</code> method call with a <code>send</code> instruction. The patch is available in <a href="https://github.com/ruby/ruby/pull/3707" class="external">this pull-request</a>.</p>
<p>By this change, the redefined <code>__send__</code> method is no longer called when it is called by a literal method name. I guess it is no problem because the following warning message is displayed for a long time.</p>
<pre><code>$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
</code></pre>
<p>This change makes the optimized case x5~x6 faster. The benchmark result is below:</p>
<pre><code>$ make benchmark COMPARE_RUBY="../../ruby/build-o3/ruby" ITEM=vm_send.yml
(snip)
# Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:------------|-----------:|---------:|
|vm_send | 18.536M| 113.778M|
| | -| 6.14x|
|vm_send_var | 18.085M| 16.595M|
| | 1.09x| -|
</code></pre> Ruby master - Feature #17279 (Open): Allow a negative step in Range#step with a blockhttps://bugs.ruby-lang.org/issues/172792020-10-22T02:23:48Zmrkn (Kenta Murata)muraken@gmail.com
<p><code>Range#step</code> prohibits a negative step when a block is given.</p>
<pre><code>>> (6..3).step(-1) {|i| p i }
Traceback (most recent call last):
5: from /home/mrkn/.rbenv/versions/2.7/bin/irb:23:in `<main>'
4: from /home/mrkn/.rbenv/versions/2.7/bin/irb:23:in `load'
3: from /home/mrkn/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.4/exe/irb:11:in `<top (required)>'
2: from (irb):1
1: from (irb):1:in `step'
ArgumentError (step can't be negative)
</code></pre>
<p>But <code>Range#step</code> allows a negative step when it is called without a block. In this case, <code>Range#step</code> creates an ArithmeticSequence, and <code>ArithmeticSequence#each</code> can iterate with a negative step.</p>
<pre><code>>> (6..3).step(-1).each {|i| p i }
6
5
4
3
=> ((6..3).step(-1))
</code></pre>
<p>I think the prohibition of a negative step in <code>Range#step</code> has already been meaningless, so it may be better to permit it for consistency.</p> Ruby master - Feature #17184 (Open): No stdlib function to perform simple string replacementhttps://bugs.ruby-lang.org/issues/171842020-09-24T11:37:04Zsheerun (Adam Stankiewicz)sheerun@sher.pl
<p>I have following simple <code>build.rb</code>:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="n">template</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s1">'template.vim'</span><span class="p">)</span>
<span class="n">script</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s1">'script.vim'</span><span class="p">)</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'app.vim'</span><span class="p">,</span> <span class="n">template</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="s2">"SCRIPT"</span><span class="p">,</span> <span class="n">script</span><span class="p">))</span>
</code></pre>
<p>And then following <code>template.vim</code>:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
SCRIPT
</code></pre>
<p>Plus following <code>script.vim</code>:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s\+"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>I'd expect that the script above produces <code>app.vim</code> with following contents:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
<span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s\+"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>Unfortunately it produces following:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
<span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>It's probably because gsub interprets <code>\+</code> in script as back-reference.</p>
<p>I tried to find replacement function in ruby that just replaces one string with something else, without interpreting replacement in any way, but surprisingly I haven't found any.. Am I mistaken?</p> Ruby master - Feature #16992 (Open): Sets: officially orderedhttps://bugs.ruby-lang.org/issues/169922020-06-26T20:30:50Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>Officially, set elements have uncertain order. This predades when Hash started being ordered (Ruby 1.9.0, Xmas 2007). Sets have since been de-facto insertion-ordered. FYI, in those 13 years, there have been about 70 commits to <code>lib/set.rb</code>.</p>
<p>I have the impression that a non-negligible amount of code in the wild rely on sets being ordered, at least under most circumstances. I feel that this should be officialized.</p>
<p>If sets are truly unordered, then why do we hesitate to make an optimization of <code>&</code> and <code>|</code>: <a href="https://bugs.ruby-lang.org/issues/15281" class="external">https://bugs.ruby-lang.org/issues/15281</a></p>
<p>See also: <a href="https://bugs.ruby-lang.org/issues/14069" class="external">https://bugs.ruby-lang.org/issues/14069</a></p> Ruby master - Feature #16986 (Open): Anonymous Struct literalhttps://bugs.ruby-lang.org/issues/169862020-06-26T06:58:53Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>How about introducing anonymous Struct literal such as <code>${a: 1, b: 2}</code>?<br>
It is almost the same as <code>Struct.new(:a, :b).new(1, 2)</code>.</p>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>In many cases, people use hash objects to represent a set of values such as <code>person = {name: "ko1", country: 'Japan'}</code> and access its values through <code>person[:name]</code> and so on. It is not easy to write (three characters <code>[:]</code>!), and it easily introduces misspelling (<code>person[:nama]</code> doesn't raise an error).</p>
<p>If we make a <code>Struct</code> object by doing <code>Person = Struct.new(:name, :age)</code> and <code>person = Person.new('ko1', 'Japan')</code>, we can access its values through <code>person.name</code> naturally. However, it costs coding. And in some cases, we don't want to name the class (such as <code>Person</code>).</p>
<p>Using <code>OpenStruct</code> (<code>person = OpenStruct.new(name: "ko1", country: "Japan")</code>), we can access it through <code>person.name</code>, but we can extend the fields unintentionally, and the performance is not good.</p>
<p>Of course, we can define a class <code>Person</code> with attr_readers. But it takes several lines.</p>
<p>To summarize the needs:</p>
<ul>
<li>Easy to write
<ul>
<li>Doesn't require declaring the class</li>
<li>Accessible through <code>person.name</code> format</li>
</ul>
</li>
<li>Limited fields</li>
<li>Better performance</li>
</ul>
<a name="Idea"></a>
<h2 >Idea<a href="#Idea" class="wiki-anchor">¶</a></h2>
<p>Introduce new literal syntax for an anonymous Struct such as: <code>${ a: 1, b: 2 }</code>.<br>
Similar to Hash syntax (with labels), but with <code>$</code> prefix to distinguish.</p>
<p>Anonymous structs which have the same member in the same order share their class.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">s1</span> <span class="o">=</span> <span class="err">$</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="n">s2</span> <span class="o">=</span> <span class="err">$</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="n">assert</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span>
<span class="n">s3</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}</span>
<span class="n">s4</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">d: </span><span class="mi">4</span><span class="p">}</span>
<span class="n">assert_equal</span> <span class="kp">false</span><span class="p">,</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s3</span>
<span class="n">assert_equal</span> <span class="kp">false</span><span class="p">,</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s4</span>
</code></pre>
<a name="Note"></a>
<h2 >Note<a href="#Note" class="wiki-anchor">¶</a></h2>
<p>Unlike Hash literal syntax, this proposal only allows <code>label: expr</code> notation. No <code>${**h}</code> syntax.<br>
This is because if we allow to splat a Hash, it can be a vulnerability by splatting outer-input Hash.</p>
<p>Thanks to this spec, we can specify anonymous Struct classes at compile time.<br>
We don't need to find or create Struct classes at runtime.</p>
<a name="Implementatation"></a>
<h2 >Implementatation<a href="#Implementatation" class="wiki-anchor">¶</a></h2>
<p><a href="https://github.com/ruby/ruby/pull/3259" class="external">https://github.com/ruby/ruby/pull/3259</a></p>
<a name="Discussion"></a>
<h1 >Discussion<a href="#Discussion" class="wiki-anchor">¶</a></h1>
<a name="Notation"></a>
<h2 >Notation<a href="#Notation" class="wiki-anchor">¶</a></h2>
<p>Matz said he thought about <code>{|a: 1, b: 2 |}</code> syntax.</p>
<a name="Performance"></a>
<h2 >Performance<a href="#Performance" class="wiki-anchor">¶</a></h2>
<p>Surprisingly, Hash is fast and Struct is slow.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Benchmark</span><span class="p">.</span><span class="nf">driver</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span>
<span class="n">r</span><span class="p">.</span><span class="nf">prelude</span> <span class="o"><<~</span><span class="no">PRELUDE</span><span class="sh">
st = Struct.new(:a, :b).new(1, 2)
hs = {a: 1, b: 2}
class C
attr_reader :a, :b
def initialize() = (@a = 1; @b = 2)
end
ob = C.new
</span><span class="no"> PRELUDE</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"ob.a"</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"hs[:a]"</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"st.a"</span>
<span class="k">end</span>
<span class="cp">__END__
Warming up --------------------------------------
ob.a 38.100M i/s - 38.142M times in 1.001101s (26.25ns/i, 76clocks/i)
hs[:a] 37.845M i/s - 38.037M times in 1.005051s (26.42ns/i, 76clocks/i)
st.a 33.348M i/s - 33.612M times in 1.007904s (29.99ns/i, 87clocks/i)
Calculating -------------------------------------
ob.a 87.917M i/s - 114.300M times in 1.300085s (11.37ns/i, 33clocks/i)
hs[:a] 85.504M i/s - 113.536M times in 1.327850s (11.70ns/i, 33clocks/i)
st.a 61.337M i/s - 100.045M times in 1.631064s (16.30ns/i, 47clocks/i)
Comparison:
ob.a: 87917391.4 i/s
hs[:a]: 85503703.6 i/s - 1.03x slower
st.a: 61337463.3 i/s - 1.43x slower
</span></code></pre>
<p>I believe we can speed up <code>Struct</code> similarly to ivar accesses, so we can improve the performance.</p>
<p>BTW, OpenStruct (os.a) is slow.</p>
<pre><code>Comparison:
hs[:a]: 92835317.7 i/s
ob.a: 85865849.5 i/s - 1.08x slower
st.a: 53480417.5 i/s - 1.74x slower
os.a: 12541267.7 i/s - 7.40x slower
</code></pre>
<p>For memory consumption, <code>Struct</code> is more lightweight because we don't need to keep the key names.</p>
<a name="Naming"></a>
<h2 >Naming<a href="#Naming" class="wiki-anchor">¶</a></h2>
<p>If we name an anonymous class, literals with the same members share the name.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">s1</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="n">a</span><span class="p">:</span><span class="mi">1</span><span class="p">}</span>
<span class="n">s2</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="n">a</span><span class="p">:</span><span class="mi">2</span><span class="p">}</span>
<span class="nb">p</span> <span class="p">[</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">]</span> <span class="c1">#=> [#<struct a=1>, #<struct a=2>]</span>
<span class="no">A</span> <span class="o">=</span> <span class="n">s1</span><span class="p">.</span><span class="nf">class</span>
<span class="nb">p</span> <span class="p">[</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">]</span> <span class="c1">#=> [#<struct A a=1>, #<struct A a=2>]</span>
</code></pre>
<p>Maybe that is not a good behavior.</p> Ruby master - Feature #16894 (Open): Integer division for Ruby 3https://bugs.ruby-lang.org/issues/168942020-05-15T03:20:39Zankane (Andrew Kane)
<p>Hi Ruby team,</p>
<p>It'd be great if division in Ruby matched what we all learned in school.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">==</span> <span class="mf">0.5</span>
</code></pre>
<p>New developers wouldn't immediately be confused when they try to do division and experienced developers could stop adding to_f to their code (typically after they get tripped up on the first run). In my experience, floating point division is way more common than floor division. This could definitely break existing code, so I understand it's a decision that shouldn't be made lightly. Overall, Ruby is really intuitive, but this is one place where it's not.</p>
<p>It looks like this was considered for Ruby 2.0 as well as few years ago in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Integer#/ の改訂 (Rejected)" href="https://bugs.ruby-lang.org/issues/5512">#5512</a>, so feel free to close if it's not something you'd like to reconsider right now.</p> Ruby master - Misc #16630 (Assigned): Deprecate pub/ruby/*snapshot* and use pub/ruby/snapshot/* i...https://bugs.ruby-lang.org/issues/166302020-02-13T08:51:43Zznz (Kazuhiro NISHIYAMA)
<p>In <a href="https://www.ruby-lang.org/en/downloads/" class="external">https://www.ruby-lang.org/en/downloads/</a>, snapshots links to <code>pub/ruby/snapshot.*</code> and <code>pub/ruby/stable-snapshot.*</code> as official snapshot tarballs now.</p>
<p>I want to change links to snapshot tarballs in <a href="https://cache.ruby-lang.org/pub/ruby/snapshot/" class="external">https://cache.ruby-lang.org/pub/ruby/snapshot/</a>.</p>
<p>They created by <a href="https://github.com/ruby/actions/" class="external">https://github.com/ruby/actions/</a> now.</p>
<p>Tarballs under <code>pub/ruby/snapshot/</code> have branch name (e.g. <code>ruby_2_7</code>) in filenames.<br>
And they are tested. (but they remain even if tests failed.)</p>
<p><code>pub/ruby/*snapshot.*</code> are not tested.<br>
And there are fewer files under <code>pub/ruby/</code> without sub-directory recently. (e.g. <code>ruby- 2.7.*</code> are in <code>pub/ruby/2.7/</code> only.)<br>
So I want to remove them.</p>
<p>Because of the plan, <code>stable-snapshot.*</code> are still snapshot of <code>ruby_2_6</code> instead of <code>ruby_2_7</code>.</p> Ruby master - Feature #16461 (Assigned): Proc#usinghttps://bugs.ruby-lang.org/issues/164612019-12-28T03:32:34Zshugo (Shugo Maeda)
<a name="Overview"></a>
<h2 >Overview<a href="#Overview" class="wiki-anchor">¶</a></h2>
<p>I propose Proc#using to support block-level refinements.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">IntegerDivExt</span>
<span class="n">refine</span> <span class="no">Integer</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">/</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">quo</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span> <span class="c1"># using IntegerDivExt in the block represented by the Proc object</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_eval</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="c1"># necessary where blocks are defined (not where Proc#using is called)</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="PoC-implementation"></a>
<h2 >PoC implementation<a href="#PoC-implementation" class="wiki-anchor">¶</a></h2>
<p>For CRuby: <a href="https://github.com/shugo/ruby/pull/2" class="external">https://github.com/shugo/ruby/pull/2</a><br>
For JRuby: <a href="https://github.com/shugo/jruby/pull/1" class="external">https://github.com/shugo/jruby/pull/1</a></p>
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>I proposed <a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086: using: option for instance_eval etc.</a> before, but it has problems:</p>
<ul>
<li>Thread safety: The same block can be invoked with different refinements in multiple threads, so it's hard to implement method caching.</li>
<li>_exec family support: {instance,class,module}_exec cannot be supported.</li>
<li>Implicit use of refinements: every blocks can be used with refinements, so there was implementation difficulty in JRuby and it has usability issue in headius's opinion.</li>
</ul>
<a name="Solutions-in-this-proposal"></a>
<h2 >Solutions in this proposal<a href="#Solutions-in-this-proposal" class="wiki-anchor">¶</a></h2>
<a name="Thread-safety"></a>
<h3 >Thread safety<a href="#Thread-safety" class="wiki-anchor">¶</a></h3>
<p>Proc#using affects the block represented by the Proc object, neither the specific Proc object nor the specific block invocation.<br>
Method calls in a block are resolved with refinements which are used by Proc#using in the block at the time.<br>
Once all possible refinements are used in the block, there is no need to invalidate method cache anymore.</p>
<p>See <a href="https://github.com/shugo/ruby/pull/2/commits/1c922614ad7d1fb43b73e195348c81da7a4546ef" class="external">these tests</a> to understand how it works.<br>
Which refinements are used is depending on the order of Proc#using invocations until all Proc#using calls are finished, but eventually method calls in a block are resolved with the same refinements.</p>
<a name="-_exec-family-support"></a>
<h3 >* _exec family support<a href="#-_exec-family-support" class="wiki-anchor">¶</a></h3>
<p><a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086</a> was an extension of _eval family, so it cannot be used with _exec family, but Proc#using is independent from _eval family, and can be used with _exec family:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">instance_exec_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_exec</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_exec_with_integer_div_ext</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="k">do</span> <span class="o">|</span><span class="n">other</span><span class="o">|</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="n">other</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="Implicit-use-of-refinements"></a>
<h3 >Implicit use of refinements<a href="#Implicit-use-of-refinements" class="wiki-anchor">¶</a></h3>
<p>Proc#using can be used only if <code>using Proc::Refinements</code> is called in the scope of the block represented by the Proc object.<br>
Otherwise, a RuntimeError is raised.</p>
<p>There are two reasons:</p>
<ul>
<li>JRuby creates a special CallSite for refinements at compile-time only when <code>using</code> is called at the scope.</li>
<li>When reading programs, it may help understanding behavior. IMHO, it may be unnecessary if libraries which uses Proc#using are well documented.</li>
</ul>
<p><code>Proc::Refinements</code> is a dummy module, and has no actual refinements.</p> Ruby master - Feature #15991 (Open): Allow questionmarks in variable nameshttps://bugs.ruby-lang.org/issues/159912019-07-08T09:18:43Zaquaj (Jérémie Bonal)
<p>Hi,</p>
<p>I thought such an issue would've already been discussed but no number of searches allowed me to find a similar request. Feel free to close if I missed a previous refusal.</p>
<p>From time to time, especially when trying to clear up complex conditional logic, I find myself wishing I could add <code>?</code> to variable names, since I got used to it while naming methods.</p>
<p>For example, currently:</p>
<pre><code>if (node? && terminal?) || (halting && (value == halting))
# ...
end
</code></pre>
<p>becomes</p>
<pre><code>last_node = self.node? && self.terminal?
halt_on_node = halting && (value == halting)
if last_node || halt_on_node
# ...
end
</code></pre>
<p><code>halt_on_node</code> is clear enough, but <code>last_node</code> feels like it would contain a node, instead of expressing its actual purpose ("is the node the last one?").<br>
Right now a developer would have two options as I see them:<br>
1 - extract the conditional to a method <code>def last_node?</code> which can be a bit much if it's the only place this code is called.<br>
2 - rename the variable something like <code>is_last_node</code>, which feels a bit silly since we're in ruby and used to seeing <code>?</code>s for predicates.</p>
<p>Trying to assign to a questionmarked variable (<code>a? = true</code>) raises a <code>SyntaxError</code>. IMHO, it would make for more coherent design to allow it, just like we do in method names.</p>
<p>I was afraid that <code>variable?</code> would be already parsed as beginning a ternary expression (<code>variable?1:3</code>) but this isn't parsed either, the only thing it's used for is for method calls (<code>a?5 <==> a?(5)</code>), so this change wouldn't disrupt any current behavior, the expression would just be looked up like any other call instead of only looking up methods.</p>
<p>The only thing I can see with this is that it might raise the issue of allowing <code>!</code>s in variable names too, which I'm not sure makes a lot of sense (unlike <code>?</code> which denotes "booleanness", a trait shared by variables and methods alike, I can't see how a variable would be "dangerous").</p> Ruby master - Feature #15837 (Open): Module#name_componentshttps://bugs.ruby-lang.org/issues/158372019-05-08T03:49:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>I sometimes wrote the expression like below to extract the components of class path:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">klass</span><span class="p">.</span><span class="nf">name</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s1">'::'</span><span class="p">).</span><span class="nf">last</span>
</code></pre>
<p>Similar expressions can be found in ruby-trunk:</p>
<pre><code>mrkn@mrkn-devel:~/src/github.com/ruby/ruby$ git grep split..::
ext/json/lib/json/common.rb: path.to_s.split(/::/).inject(Object) do |p, c|
ext/openssl/lib/openssl/config.rb: refsec, ref = ref.split('::', 2)
ext/psych/lib/psych/visitors/yaml_tree.rb: method = "visit_#{(klass.name || '').split('::').join('_')}"
lib/bundler/cli/gem.rb: constant_array = constant_name.split("::")
lib/bundler/vendor/molinillo/lib/molinillo/errors.rb: solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
lib/bundler/vendor/thor/lib/thor/parser/argument.rb: class_name = self.class.name.split("::").last
lib/bundler/vendor/thor/lib/thor/parser/arguments.rb: class_name = self.class.name.split("::").last.downcase
lib/optparse/version.rb: pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
lib/optparse/version.rb: path.split(/::|\//).inject(base) do |klass, name|
lib/rdoc/any_method.rb: name = @full_name.split('::')
lib/rdoc/context.rb: names = ename.split('::')
lib/rdoc/context.rb: path = [prefix] + path.split('::')
lib/rdoc/method_attr.rb: $1.split('::').last. # ClassName => class_name
lib/rdoc/parser/c.rb: ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
lib/rdoc/parser/ruby.rb: obj = name_t[:text].split("::").inject(Object) do |state, item|
lib/rdoc/store.rb: name = klass_name.split('::').last
lib/rdoc/store.rb: File.join @path, *klass_name.split('::')
lib/rdoc/store.rb: method_name = method_name.split('::').last
lib/rss/atom.rb: "#{self.class.name.split(/::/).last.downcase}="
lib/rss/atom.rb: target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
lib/rss/atom.rb: target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
lib/rss/rss.rb: tag_name = klass.name.split(/::/).last
spec/bundler/support/artifice/fail.rb: const = name.split("::").reduce(Object) {|mod, sym| mod.const_get(sym) }
spec/mspec/lib/mspec/utils/name_map.rb: c.split('::').inject(base) do |dir, name|
spec/mspec/lib/mspec/utils/name_map.rb: name = mapping[c.split('::').last] || mapping.fetch(:default)
</code></pre>
<p>I think we need <code>Module#name_components</code> method that returns the array of symbols (or string, I prefer symbols) which comes from splitting name by <code>::</code>.</p> Ruby master - Bug #15764 (Open): Whitespace and control characters should not be permitted in tokenshttps://bugs.ruby-lang.org/issues/157642019-04-11T20:59:47ZBatmanAoD (Kyle Strand)kyle.j.strand@gmail.com
<p>As of Ruby 2.5.1p57, it appears that all valid Unicode code-points above 128 are permitted in tokens. This includes whitespace and control characters.</p>
<p>This was demonstrated here: <a href="https://gist.github.com/qrohlf/7045823" class="external">https://gist.github.com/qrohlf/7045823</a></p>
<p>I have attached the raw download from the above gist.</p>
<p>The issue has been discussed on StackOverflow: <a href="https://stackoverflow.com/q/34455427/1858225" class="external">https://stackoverflow.com/q/34455427/1858225</a></p>
<p>I would say this is arguably a bug, but I am marking this ticket as a "feature" since the current behavior could be considered by-design.</p> Ruby master - Feature #15554 (Open): warn/error passing a block to a method which never use a blockhttps://bugs.ruby-lang.org/issues/155542019-01-22T04:48:10Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Warn or raise an ArgumentError if block is passed to a method which does not use a block.<br>
In other words, detect "block user methods" implicitly and only "block user methods" can accept a block.</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>Sometimes, we pass a block to a method which ignores the passed block accidentally.</p>
<pre><code>def my_open(name)
open(name)
end
# user hopes it works as Kernel#open which invokes a block with opened file.
my_open(name){|f| important_work_with f }
# but simply ignored...
</code></pre>
<p>To solve this issue, this feature request propose showing warnings or raising an exception on such case.</p>
<p>Last developer's meeting, matz proposed <code>&nil</code> which declares this method never receive a block. It is explicit, but it is tough to add this <code>&nil</code> parameter declaration to all of methods (do you want to add it to <code>def []=(i, e, &nil)</code>?).<br>
(I agree <code>&nil</code> is valuable on some situations)</p>
<a name="Spec"></a>
<h1 >Spec<a href="#Spec" class="wiki-anchor">¶</a></h1>
<a name="Define-use-a-block-methods"></a>
<h2 >Define "use a block" methods<a href="#Define-use-a-block-methods" class="wiki-anchor">¶</a></h2>
<p>We need to define which method accepts a block and which method does not.</p>
<ul>
<li>(1) method has a block parameter (<code>&b</code>)</li>
<li>(2) method body has `yield'</li>
<li>(3) method body has <code>super</code> (ZSUPER in internal terminology) or <code>super(...)</code>
</li>
<li>(4) method body has singleton method (optional)</li>
</ul>
<p>(1) and (2) is very clear. I need to explain about (3) and (4).</p>
<p>(3). <code>super</code> (ZSUPER) passes all parameters as arguments. So there is no surprise that which can accept <code>block</code>.<br>
However <code>super(...)</code> also passes a block if no explicit block passing (like <code>super(){}</code> or <code>super(&b)</code>) are written.<br>
I'm not sure we need to continue this strange specification, but to keep compatibility depending this spec, I add this rule.</p>
<p>(4). surprisingly, the following code invoke a block:</p>
<pre><code>def foo
class << Object.new
yield
end
end
foo{ p :ok } #=> :ok
</code></pre>
<p>I'm also not sure we need to keep this spec, but to allow this spec, I added (4) rule.<br>
Strictly speaking, it is not required, but we don't keep the link from singleton class ISeq to lexical parent iseq now, so I added it.</p>
<a name="Exceptional-cases"></a>
<h2 >Exceptional cases<a href="#Exceptional-cases" class="wiki-anchor">¶</a></h2>
<p>A method called by <code>super</code> doesn<code>t warn warning even if this method doesn't use a block. The rule (3) can pass blocks easily and there are many methods don</code>t use a block.</p>
<p>So my patch ignores callings by <code>super</code>.</p>
<a name="corner-cases"></a>
<h2 >corner cases<a href="#corner-cases" class="wiki-anchor">¶</a></h2>
<p>There are several cases to use block without (1)-(4) rules.</p>
<h3>
<code>Proc.new/proc/lambda</code> without a block</h3>
<p>Now it was deprecated in r66772 (<a class="changeset" title="proc.c: proc without block * proc.c (proc_new): promoted lambda/proc/Proc.new with no block in..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/9f1fb0a17febc59356d58cef5e98db61a3c03550">9f1fb0a17febc59356d58cef5e98db61a3c03550</a>).<br>
Related discussion: [Bug <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Proc.new with no block shouldn't always warn (Rejected)" href="https://bugs.ruby-lang.org/issues/15539">#15539</a>]</p>
<a name="block_given"></a>
<h3 ><code>block_given?</code><a href="#block_given" class="wiki-anchor">¶</a></h3>
<p><code>block_given?</code> expects block, but I believe we use it with <code>yield</code> or a block parameter.<br>
If you know the usecase without them, please tell us.</p>
<h3>
<code>yield</code> in <code>eval</code>
</h3>
<p>We can't know <code>yield</code> (or (3), (4) rule) in an <code>eval</code> evaluating string at calling time.</p>
<pre><code>def foo
eval('yield`)
end
foo{} # at calling time,
# we can't know the method foo can accept a block or not.
</code></pre>
<p>So I added a warning to use <code>yield</code> in <code>eval</code> like that: <code>test.rb:4: warning: use yield in eval will not be supported in Ruby 3.</code></p>
<p>Workaround is use a block parameter explicitly.</p>
<pre><code>def foo &b
eval('b.call')
end
foo{ p :ok }
</code></pre>
<a name="Implementation"></a>
<h1 >Implementation<a href="#Implementation" class="wiki-anchor">¶</a></h1>
<p>Strategy is:</p>
<ul>
<li>[compile time] introduce <code>iseq::has_yield</code> field and check it if the iseq (or child iseq) contains <code>yield</code> (or something)</li>
<li>[calling time] if block is given, check <code>iseq::has_yield</code> flag and show warning (or raise an exception)</li>
</ul>
<p><a href="https://gist.github.com/ko1/c9148ad0224bf5befa3cc76ed2220c0b" class="external">https://gist.github.com/ko1/c9148ad0224bf5befa3cc76ed2220c0b</a></p>
<p>On this patch, now it raises an error to make it easy to detect.<br>
It is easy to switch to show the warning.</p>
<a name="Evaluation-and-discussion"></a>
<h1 >Evaluation and discussion<a href="#Evaluation-and-discussion" class="wiki-anchor">¶</a></h1>
<p>I tried to avoid ruby's tests.</p>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786</a></p>
<p>Here is a patch.</p>
<p>There are several patterns to avoid warnings.</p>
<a name="tests-for-block_given-Procnew-and-similar-without-block"></a>
<h2 >tests for <code>block_given?</code>, <code>Proc.new</code> (and similar) without block<a href="#tests-for-block_given-Procnew-and-similar-without-block" class="wiki-anchor">¶</a></h2>
<p>Add a dummy block parameter.<br>
It is test-specific issue.</p>
<h2>empty <code>each</code>
</h2>
<p>Some tests add <code>each</code> methods do not <code>yield</code>, like: <code>def each; end</code>.<br>
Maybe test-specific issue, and adding a dummy block parameter.</p>
<a name="Subtyping-duck-typing"></a>
<h2 >Subtyping / duck typing<a href="#Subtyping-duck-typing" class="wiki-anchor">¶</a></h2>
<p><a href="https://github.com/ruby/ruby/blob/c01a5ee85e2d6a7128cccafb143bfa694284ca87/lib/optparse.rb#L698" class="external">https://github.com/ruby/ruby/blob/c01a5ee85e2d6a7128cccafb143bfa694284ca87/lib/optparse.rb#L698</a></p>
<p>This <code>parse</code> method doesn't use <code>yield</code>, but other sub-type's <code>parse</code> methods use.</p>
<h2>
<code>super</code> with <code>new</code> method</h2>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L61" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L61</a></p>
<p>This method override <code>Class#new</code> method and introduce a hook with block (yield a block in this hook code).</p>
<p><a href="https://github.com/ruby/ruby/blob/trunk/lib/rubygems/package/tar_writer.rb#L81" class="external">https://github.com/ruby/ruby/blob/trunk/lib/rubygems/package/tar_writer.rb#L81</a></p>
<p>In this method, call <code>super</code> and it also passing a block. However, called <code>initialize</code> doesn't use a block.</p>
<a name="Change-robustness"></a>
<h2 >Change robustness<a href="#Change-robustness" class="wiki-anchor">¶</a></h2>
<p>This change reduce robustness for API change.</p>
<p><code>Delegator</code> requires to support <code>__getobj__</code> for client classes.<br>
Now <code>__getobj__</code> should accept block but most of <code>__getobj__</code> clients do not call given block.</p>
<p><a href="https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L80" class="external">https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L80</a></p>
<p>This is because of delegator.rb's API change.</p>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L86" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L86</a></p>
<p>Nobu says calling block is not required (ignoring a block is no problem) so it is not a bug for delegator client classes.</p>
<a name="Found-issues"></a>
<h2 >Found issues.<a href="#Found-issues" class="wiki-anchor">¶</a></h2>
<pre><code>[ 2945/20449] Rinda::TestRingServer#test_do_reply = 0.00 s
1) Error:
Rinda::TestRingServer#test_do_reply:
ArgumentError: passing block to the method "with_timeout" (defined at /home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:787) is never used.
/home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:635:in `test_do_reply'
[ 2946/20449] Rinda::TestRingServer#test_do_reply_local = 0.00 s
2) Error:
Rinda::TestRingServer#test_do_reply_local:
ArgumentError: passing block to the method "with_timeout" (defined at /home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:787) is never used.
/home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:657:in `test_do_reply_local'
[10024/20449] TestGemRequestSetGemDependencyAPI#test_platform_mswin = 0.01 s
3) Error:
TestGemRequestSetGemDependencyAPI#test_platform_mswin:
ArgumentError: passing block to the method "util_set_arch" (defined at /home/ko1/src/ruby/trunk/lib/rubygems/test_case.rb:1053) is never used.
/home/ko1/src/ruby/trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb:655:in `test_platform_mswin'
[10025/20449] TestGemRequestSetGemDependencyAPI#test_platforms = 0.01 s
4) Error:
TestGemRequestSetGemDependencyAPI#test_platforms:
ArgumentError: passing block to the method "util_set_arch" (defined at /home/ko1/src/ruby/trunk/lib/rubygems/test_case.rb:1053) is never used.
/home/ko1/src/ruby/trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb:711:in `test_platforms'
</code></pre>
<p>These 4 detection show the problem. <code>with_timeout</code> method (used in Rinda test) and <code>util_set_arch</code> method (used in Rubygems test) simply ignore the given block.<br>
So these tests are simply ignored.</p>
<p>I reported them. (<a href="https://github.com/rubygems/rubygems/issues/2601" class="external">https://github.com/rubygems/rubygems/issues/2601</a>)</p>
<a name="raise-an-error-or-show-a-warning"></a>
<h2 >raise an error or show a warning?<a href="#raise-an-error-or-show-a-warning" class="wiki-anchor">¶</a></h2>
<p>At least, Ruby 2.7 should show warning for this kind of violation with <code>-w</code>.<br>
How about for Ruby3?</p> Ruby master - Feature #15445 (Open): Reject '.123' in Float() methodhttps://bugs.ruby-lang.org/issues/154452018-12-21T00:16:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>Since ruby 1.8, Ruby occurs a syntax error for "." floating literal.<br>
But Float() method accepts such form now.</p>
<p>I propose to reject "." form even in Float() method.</p> Ruby master - Feature #15330 (Open): autoload_relativehttps://bugs.ruby-lang.org/issues/153302018-11-21T23:43:41Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I'd like to propose a way to autoload a constant using a relative path.</p>
<p>It could look like:</p>
<pre><code>autoload_relative :MyConst, 'models/my_const'
</code></pre>
<p>My proposal raises two questions:</p>
<ol>
<li>what's the future of <code>autoload</code>?</li>
</ol>
<p>I believe that <code>autoload</code> has been there for years, it is used successfully and has no real alternative.</p>
<p>I looked at a sample of 430 top gems (took the 500 top ranked according to Libraries.io, removed those that I failed to process). The number of those gems that appear to use <code>autoload</code> at least once is 94 of those (22%).</p>
<p>The number of lines in the code where <code>autoload</code> is called can be quite big. The top 5 are:<br>
vagrant: 235<br>
yard: 206<br>
ffaker: 155<br>
aws-sdk: 152<br>
rdoc: 92</p>
<p>This is a minimum bound, as some gems might be using loops, my processing would only detect the one place in the code with <code>autoload</code>.</p>
<ol start="2">
<li>are many autoladed paths relative?</li>
</ol>
<p>My preliminary numbers indicate that of the 94 gems using autoload, at least 75 are autoloading some relative files. That's a lower bound, as my algorithm is pretty crude and will only count the simplest cases as being relative. An example of gem my algorithm does not detect is <code>yard</code>, because the author wrote a small method to map the relative paths to global paths (code here: <a href="https://github.com/lsegal/yard/blob/master/lib/yard/autoload.rb#L3" class="external">https://github.com/lsegal/yard/blob/master/lib/yard/autoload.rb#L3</a> )</p>
<p>Of those where my processing detects the relative requires, a vast majority are relative. The average is that 94% of autoloaded files are relative and would benefit from <code>require_relative</code></p>
<p>In summary: I am convinced that <code>autoload</code> should remain in Ruby indefinitely. <code>autoload_relative</code> would actually be more useful than <code>autoload</code>. Even if the future of <code>autoload</code> remains uncertain, I would recommend adding <code>autoload_relative</code>; if it is ever decided to actually remove <code>autoload</code>, removing <code>autoload_relative</code> would not really add to the (huge) burden of gem maintainers.</p> Ruby master - Feature #15277 (Open): at_exechttps://bugs.ruby-lang.org/issues/152772018-11-02T19:23:47Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>There's currently no easy way to have code executed before a subsequent call to <code>exec</code>. One has to monkey-patch the builtin method.</p>
<p>I'd like to propose a new method <code>at_exec</code> that would be very similar to <code>at_exit</code>, except that the callbacks are triggered before the current process is replaced by the external command.</p>
<pre><code># This would output "Hello", "Bye", and "Foo"
at_exec { puts "Bye!" }
puts "Hello"
exec "echo Foo"
</code></pre>
<p>Use case: we roll our own in <code>DeepCover</code>. Some test suites will call <code>exec</code>, and we need to store our counters before that happens.</p> Ruby master - Feature #15192 (Open): Introduce a new "shortcut assigning" syntax to convenient se...https://bugs.ruby-lang.org/issues/151922018-10-02T04:54:28Zjjyr (Jinyang Jiang)jjyruby@gmail.com
<p>Motivation:</p>
<p>Introduce a new syntax for convenient setup instance variables for objects.</p>
<p>The problem:</p>
<p>Currently, setup instance variables in Ruby is too verbose.<br>
Basically, we need to write the meaningless assigning code again and again to assign variables</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Person</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">:,</span> <span class="n">age</span><span class="p">:,</span> <span class="n">gender</span><span class="p">:,</span> <span class="n">country</span><span class="p">:)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
<span class="vi">@gender</span> <span class="o">=</span> <span class="n">gender</span>
<span class="vi">@country</span> <span class="o">=</span> <span class="n">country</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># we can use Struct to avoiding this</span>
<span class="no">Person</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">:name</span><span class="p">,</span> <span class="ss">:age</span><span class="p">,</span> <span class="ss">:gender</span><span class="p">,</span> <span class="ss">:country</span><span class="p">,</span> <span class="ss">keyword_init: </span><span class="kp">true</span><span class="p">)</span>
<span class="c1"># let's see a real-world case, which can't use Struct to describe an initializing process, from https://github.com/ciri-ethereum/ciri/blob/748985ccf7a620a2e480706a5a6b38f56409d487/lib/ciri/devp2p/server.rb#L54</span>
<span class="c1"># Because we want to do something more than just assigning instance variables</span>
<span class="k">class</span> <span class="nc">Server</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">private_key</span><span class="p">:,</span> <span class="n">protocol_manage</span><span class="p">:,</span> <span class="ss">bootstrap_nodes: </span><span class="p">[],</span>
<span class="ss">node_name: </span><span class="s1">'Ciri'</span><span class="p">,</span> <span class="ss">tcp_host: </span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="ss">tcp_port: </span><span class="mi">33033</span><span class="p">)</span>
<span class="vi">@private_key</span> <span class="o">=</span> <span class="n">private_key</span>
<span class="vi">@node_name</span> <span class="o">=</span> <span class="n">node_name</span>
<span class="vi">@bootstrap_nodes</span> <span class="o">=</span> <span class="n">bootstrap_nodes</span>
<span class="vi">@protocol_manage</span> <span class="o">=</span> <span class="n">protocol_manage</span>
<span class="n">server_node_id</span> <span class="o">=</span> <span class="no">NodeID</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">)</span>
<span class="n">caps</span> <span class="o">=</span> <span class="p">[</span><span class="no">Cap</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s1">'eth'</span><span class="p">,</span> <span class="ss">version: </span><span class="mi">63</span><span class="p">)]</span>
<span class="vi">@handshake</span> <span class="o">=</span> <span class="no">ProtocolHandshake</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">version: </span><span class="no">BASE_PROTOCOL_VERSION</span><span class="p">,</span> <span class="ss">name: </span><span class="vi">@node_name</span><span class="p">,</span> <span class="ss">id: </span><span class="n">server_node_id</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="ss">caps: </span><span class="n">caps</span><span class="p">)</span>
<span class="vi">@tcp_host</span> <span class="o">=</span> <span class="n">tcp_host</span>
<span class="vi">@tcp_port</span> <span class="o">=</span> <span class="n">tcp_port</span>
<span class="vi">@dial</span> <span class="o">=</span> <span class="no">Dial</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">bootstrap_nodes: </span><span class="n">bootstrap_nodes</span><span class="p">,</span> <span class="ss">private_key: </span><span class="n">private_key</span><span class="p">,</span> <span class="ss">handshake: </span><span class="vi">@handshake</span><span class="p">)</span>
<span class="vi">@network_state</span> <span class="o">=</span> <span class="no">NetworkState</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">protocol_manage</span><span class="p">)</span>
<span class="vi">@dial_scheduler</span> <span class="o">=</span> <span class="no">DialScheduler</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@network_state</span><span class="p">,</span> <span class="vi">@dial</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># Introduce a new "shortcut assigning" syntax for convenient setup</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="c1"># use @ prefix to describe instance variables.</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="vi">@name</span><span class="p">:,</span> <span class="vi">@age</span><span class="p">:,</span> <span class="vi">@gender</span><span class="p">:,</span> <span class="vi">@country</span><span class="p">:)</span>
<span class="k">end</span>
<span class="c1"># equal to</span>
<span class="k">def</span> <span class="nf">initialize2</span><span class="p">(</span><span class="nb">name</span><span class="p">:,</span> <span class="n">age</span><span class="p">:,</span> <span class="n">gender</span><span class="p">:,</span> <span class="n">country</span><span class="p">:)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
<span class="vi">@gender</span> <span class="o">=</span> <span class="n">gender</span>
<span class="vi">@country</span> <span class="o">=</span> <span class="n">country</span>
<span class="k">end</span>
<span class="c1"># it should also work on position style arguments</span>
<span class="k">def</span> <span class="nf">initialize2</span><span class="p">(</span><span class="vi">@name</span><span class="p">,</span> <span class="vi">@age</span><span class="p">,</span> <span class="vi">@gender</span><span class="p">,</span> <span class="vi">@country</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># Our real-world case can be rewritten as below</span>
<span class="k">class</span> <span class="nc">Server</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">:,</span> <span class="vi">@protocol_manage</span><span class="p">:,</span> <span class="vi">@bootstrap_nodes</span><span class="p">:</span> <span class="p">[],</span>
<span class="vi">@node_name</span><span class="p">:</span> <span class="s1">'Ciri'</span><span class="p">,</span> <span class="vi">@tcp_host</span><span class="p">:</span> <span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="vi">@tcp_port</span><span class="p">:</span> <span class="mi">33033</span><span class="p">)</span>
<span class="n">server_node_id</span> <span class="o">=</span> <span class="no">NodeID</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">)</span>
<span class="n">caps</span> <span class="o">=</span> <span class="p">[</span><span class="no">Cap</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s1">'eth'</span><span class="p">,</span> <span class="ss">version: </span><span class="mi">63</span><span class="p">)]</span>
<span class="vi">@handshake</span> <span class="o">=</span> <span class="no">ProtocolHandshake</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">version: </span><span class="no">BASE_PROTOCOL_VERSION</span><span class="p">,</span> <span class="ss">name: </span><span class="vi">@node_name</span><span class="p">,</span> <span class="ss">id: </span><span class="n">server_node_id</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="ss">caps: </span><span class="n">caps</span><span class="p">)</span>
<span class="vi">@dial</span> <span class="o">=</span> <span class="no">Dial</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">bootstrap_nodes: </span><span class="vi">@bootstrap_nodes</span><span class="p">,</span> <span class="ss">private_key: </span><span class="vi">@private_key</span><span class="p">,</span> <span class="ss">handshake: </span><span class="vi">@handshake</span><span class="p">)</span>
<span class="vi">@network_state</span> <span class="o">=</span> <span class="no">NetworkState</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@protocol_manage</span><span class="p">)</span>
<span class="vi">@dial_scheduler</span> <span class="o">=</span> <span class="no">DialScheduler</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@network_state</span><span class="p">,</span> <span class="vi">@dial</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># consider to keep consistency, this "shortcut assigning" syntax should work for non-initialize methods</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="vi">@still_works</span><span class="p">)</span>
<span class="nb">p</span> <span class="vi">@still_works</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #15112 (Open): Introducing the short form of `STDERR.puts expr.inspect`.https://bugs.ruby-lang.org/issues/151122018-09-13T06:15:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>I sometimes write <code>STDERR.puts obj.inspect</code> to print debug message to standard error.<br>
I want to write it as <code>STDERR.p obj</code>.<br>
It can be realized by introducing <code>p</code> singleton method in <code>STDERR</code> object.</p> Ruby master - Feature #14982 (Open): Improve namespace system in ruby to avoiding top-level name...https://bugs.ruby-lang.org/issues/149822018-08-11T04:26:06Zjjyr (Jinyang Jiang)jjyruby@gmail.com
<p>Updated: <a href="https://bugs.ruby-lang.org/issues/14982#note-5" class="external">https://bugs.ruby-lang.org/issues/14982#note-5</a></p>
<a name="Why"></a>
<h2 >Why<a href="#Why" class="wiki-anchor">¶</a></h2>
<p>Ruby has evaluation all class/module names in top-level context(aka TOPLEVEL_BINDING).<br>
As a user we basically hard to know how many names in the current context, is causing chaos in some cases. For example:</p>
<p>case 1:</p>
<p>Put common used errors class in a single file, like below</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># utils/errors.rb</span>
<span class="k">class</span> <span class="nc">FooError</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">BarError</span>
<span class="k">end</span>
</code></pre>
<p>In other files under 'utils' we want to use those errors, so the best practice is to use <code>require_relative 'errors'</code> in each file we need.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># utils/binary_helper.rb</span>
<span class="c1"># we forget require errors</span>
<span class="k">module</span> <span class="nn">BinaryHelper</span>
<span class="c1"># ...</span>
<span class="k">raise</span> <span class="no">BarError</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</code></pre>
<p>But sometime we may forget to require dependencies in a file, it's hard to notice because<br>
if RubyVM already execute the requires we still can access the name BarError,</p>
<p>but if user directly to require 'utils/binary_helper', he/she will got an NameError.</p>
<p>case 2:</p>
<p>Two gems use same top-level module name, so we can't use them together</p>
<a name="The-Reason-of-The-Problem"></a>
<h2 >The Reason of The Problem<a href="#The-Reason-of-The-Problem" class="wiki-anchor">¶</a></h2>
<p>The reason is we let module author to decision which module user can use. ('require' is basically evaluation, highly dependent on the module author's design)</p>
<p>But we should let users control which names to use and available in context. As many other popular languages dose(Rust, Python..)</p>
<p>I think the solution is basically the same philosophy compares to refinement feature.</p>
<a name="The-Design"></a>
<h2 >The Design<a href="#The-Design" class="wiki-anchor">¶</a></h2>
<p>I propose an improved namespace to Ruby, to solve the problems and still compatible with the current Ruby module system.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">end</span>
<span class="c1"># introduce Kernel#namespace</span>
<span class="n">namespace</span> <span class="ss">:Hello</span> <span class="k">do</span>
<span class="c1"># avoiding namespace chaos</span>
<span class="c1"># Foo -> NameError, can't access TOPLEVEL_BINDING directly</span>
<span class="c1"># Kernel#import method, introduce Foo name from TOPLEVEL_BINDING</span>
<span class="n">import</span> <span class="ss">:Foo</span>
<span class="c1"># in a namespace user can only access imported name</span>
<span class="no">Foo</span>
<span class="c1"># import constant to another alias name</span>
<span class="c1"># can avoid writing nested module/class names</span>
<span class="n">import</span> <span class="ss">:"A::B::C::D"</span><span class="p">,</span> <span class="ss">as: :E</span>
<span class="c1"># require then import, for convenient </span>
<span class="n">import</span> <span class="ss">:"A::B::C::D"</span><span class="p">,</span> <span class="ss">as: :E</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="c1"># import same name from two gems</span>
<span class="n">import</span> <span class="ss">:"Foo"</span><span class="p">,</span> <span class="ss">as: :Foo_A</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'foo_a'</span>
<span class="n">import</span> <span class="ss">:"Foo"</span><span class="p">,</span> <span class="ss">as: :Foo_B</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'foo_b'</span>
<span class="c1"># import names in batch</span>
<span class="n">import</span> <span class="sx">%i{"A::B::C::D", "AnotherClass"}</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="c1"># import and alias in batch</span>
<span class="n">import</span> <span class="p">{</span><span class="ss">:"A::B::C::D"</span> <span class="o">=></span> <span class="ss">:E</span><span class="p">,</span> <span class="ss">:Foo</span> <span class="o">=></span> <span class="no">Foo2</span><span class="p">},</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="k">def</span> <span class="nf">xxx</span>
<span class="c1"># can access all names in namespace scope</span>
<span class="p">[</span><span class="no">Foo</span><span class="p">,</span> <span class="no">Foo_A</span><span class="p">,</span> <span class="no">Foo_B</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Hello</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># -> module. namespace is just a module</span>
<span class="no">Hello</span><span class="o">::</span><span class="no">Bar</span> <span class="c1"># so we do not broken current ruby module design</span>
<span class="c1"># namespace system is intent to let user to control names in context</span>
<span class="c1"># So user can choose use the old require way</span>
<span class="nb">require</span> <span class="s1">'hello'</span>
<span class="no">Hello</span><span class="o">::</span><span class="no">Bar</span>
<span class="c1"># Or user can use namespace system as we do in hello.rb</span>
<span class="n">namespace</span> <span class="ss">:Example</span> <span class="k">do</span>
<span class="n">import</span> <span class="ss">:"Hello::Bar"</span><span class="p">,</span> <span class="ss">as: :Bar</span>
<span class="no">Bar</span> <span class="c1"># ok</span>
<span class="no">Foo</span> <span class="c1"># name error, cause we do not import Foo in :Example namespace</span>
<span class="k">end</span>
<span class="no">Foo</span> <span class="c1"># ok, cause Foo is loaded in TOPLEVEL_BINDING</span>
<span class="c1"># define nested namespace</span>
<span class="c1"># more clear syntax than “module Example::NestedExample”</span>
<span class="n">namespace</span> <span class="ss">:NestedExample</span><span class="p">,</span> <span class="ss">under: </span><span class="no">Example</span> <span class="k">do</span>
<span class="k">end</span>
<span class="n">namespace</span> <span class="ss">:Example2</span> <span class="k">do</span>
<span class="n">namespace</span> <span class="ss">:NestedExample</span> <span class="k">do</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Pros:</p>
<ul>
<li>Completely compatible with the current module system, a gem user can completely ignore whether a gem is write in Namespace or not.</li>
<li>User can completely control which names in current context/scope.</li>
<li>May solve the top module name conflict issue(depends on VM implementation).</li>
<li>Avoid introducing new keyword and syntax.</li>
<li>Type hint or name hint can be more accuracy under namespace(not sure).</li>
</ul>
<p>Cons:</p>
<ul>
<li>Need to modify Ruby VM to support the feature.</li>
</ul> Ruby master - Feature #14927 (Open): Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/149272018-07-20T18:13:55ZAnonymous
<p>Just a proof concept I wanted to share. Maybe it could be useful?</p>
<p>Say you want to load all the .rb files in your lib directory:</p>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="no">Dir</span><span class="p">[</span><span class="s1">'lib/**/*.rb'</span><span class="p">].</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span> <span class="nb">load</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="p">}</span>
</code></pre>
<p>This approach may not work if your files have dependencies like that:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># lib/foo.rb</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">Bar</span>
<span class="k">end</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># lib/bar.rb</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="k">end</span>
</code></pre>
<p>Foo class needs Bar class. You will get a NameError (uninitialized constant Bar).</p>
<p>So in my personal projects, I use this algorithm to load all my files and to automatically take care of dependencies (class/include):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">boot</span><span class="p">(</span><span class="n">files</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">i</span> <span class="o"><</span> <span class="n">files</span><span class="p">.</span><span class="nf">length</span>
<span class="k">begin</span>
<span class="nb">load</span><span class="p">(</span><span class="n">files</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="k">rescue</span> <span class="no">NameError</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">while</span> <span class="n">i</span> <span class="o">></span> <span class="mi">0</span>
<span class="n">files</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">files</span><span class="p">.</span><span class="nf">shift</span><span class="p">)</span>
<span class="n">i</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="n">files</span><span class="p">.</span><span class="nf">shift</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="n">boot</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'lib/**/*.rb'</span><span class="p">]</span> <span class="c1"># It works! foo.rb and bar.rb are properly loaded.</span>
</code></pre>
<p>My point is: it would be cool if Kernel#load could receive an array of filenames (to load all these files in the proper order). So we could load all our libs with just a single line:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">load</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'{path1,path2}/**/*.rb'</span><span class="p">]</span>
</code></pre> Ruby master - Misc #14760 (Open): cross-thread IO#close semanticshttps://bugs.ruby-lang.org/issues/147602018-05-15T10:04:52Znormalperson (Eric Wong)normalperson@yhbt.net
<p>I wrote about cross-thread IO#close in ruby-core, but I'm not sure if it's a bug<br>
or not to have missing support for IO.select and IO.copy_stream:</p>
<p>IO.select -<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/86655" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/86655</a><br>
<a href="https://public-inbox.org/ruby-core/20180423133946.GA6019@dcvr/" class="external">https://public-inbox.org/ruby-core/20180423133946.GA6019@dcvr/</a></p>
<p>IO.copy_stream -<br>
<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/87040" class="external">http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/87040</a><br>
<a href="https://public-inbox.org/ruby-core/20180515095315.GA15909@dcvr/" class="external">https://public-inbox.org/ruby-core/20180515095315.GA15909@dcvr/</a></p>
<p>I know the IO.select case in 1.9+ differs from 1.8, and IO.copy_stream wasn't in<br>
1.8, but I guess the current behavior is that it isn't consistent with normal IO<br>
methods. IO.copy_stream will also behave "normally" and raise IOError if it<br>
somehow hits non-optimized cases and ends up calling Ruby methods, but my<br>
example in <a href="https://blade.ruby-lang.org/ruby-core/87040">[ruby-core:87040]</a> did not hit that case.</p>
<p>On one hand, I'm not a fan of "nanny features" like deadlock detection for<br>
threading. On the other hand, I value consistency and we already went down the<br>
rabbit hole of supporting current users of rb_thread_io_blocking_region.</p>
<p>Anyways, I can implement these if desired since I have additional work planned<br>
in this area anyways (auto-fiber).</p> Ruby master - Feature #14724 (Open): chains of inequalitieshttps://bugs.ruby-lang.org/issues/147242018-04-30T06:36:57Zgotoken (Kentaro Goto)gotoken@gmail.com
<p>In mathematics, chain of inequations is a shorthand notation for the conjunction of several inequations involving common expressions.</p>
<p>For example, <code>a < b <= c</code> for <code>a < b && b <= c</code></p>
<p>Chain notation makes code clearer, in particular, long common expression cases will be so. E.g.,</p>
<pre><code>cur.to_i - 2 <= timeval.tv_sec <= cur.to_i
</code></pre>
<p>is easier to read than</p>
<pre><code>cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i
</code></pre>
<p>because in the latter case we have to verify whether <code>timeval.tv_sec</code> is common or not by eyes.</p>
<p>Current syntax allows but redefining builtin methods are considered not practical. So here I request as a new syntax for the chains.</p>
<a name="Use-cases-applicable-conjunctions"></a>
<h3 >Use cases (applicable conjunctions)<a href="#Use-cases-applicable-conjunctions" class="wiki-anchor">¶</a></h3>
<p>lib/matrix.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">unless</span> <span class="mi">0</span> <span class="o"><=</span> <span class="n">column</span> <span class="o">&&</span> <span class="n">column</span> <span class="o"><</span> <span class="n">column_count</span>
</code></pre>
<p>lib/time.rb documents:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="c1"># block. For example:</span>
<span class="c1">#</span>
<span class="c1"># Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}</span>
</code></pre>
<p>spec/ruby/optional/capi/bignum_spec.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">raise</span> <span class="s2">"Bignum#coerce returned Fixnum"</span> <span class="k">if</span> <span class="n">fixnum_min</span> <span class="o"><=</span> <span class="n">n</span> <span class="o">&&</span> <span class="n">n</span> <span class="o"><=</span> <span class="n">fixnum_max</span>
</code></pre>
<p>test/fiddle/test_import.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">assert</span><span class="p">(</span><span class="n">cur</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">-</span> <span class="mi">2</span> <span class="o"><=</span> <span class="n">timeval</span><span class="p">.</span><span class="nf">tv_sec</span> <span class="o">&&</span> <span class="n">timeval</span><span class="p">.</span><span class="nf">tv_sec</span> <span class="o"><=</span> <span class="n">cur</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span>
</code></pre>
<p>tool/jisx0208.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">unless</span> <span class="mh">0x8140</span> <span class="o"><=</span> <span class="n">sjis</span> <span class="o">&&</span> <span class="n">sjis</span> <span class="o"><=</span> <span class="mh">0xFCFC</span>
</code></pre> Ruby master - Feature #14609 (Open): Let `Kernel#p` without an argument print the receiverhttps://bugs.ruby-lang.org/issues/146092018-03-16T01:29:09Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p><code>Kernel#p(obj)</code> prints <code>obj</code> as <code>inspect</code>ed.<br>
How about printing the receiver if an argument is not given?</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>We recently introduced <code>yield_self</code>, which encourages block chain.</p>
<p><a href="https://zverok.github.io/blog/2018-01-24-yield_self.html" class="external">https://zverok.github.io/blog/2018-01-24-yield_self.html</a><br>
Quoting from this article, we can write method chain with blocks:</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }
.yield_self { |id| "server:#{id}" }
</code></pre>
<p>There is a small problem concerning debugging.<br>
If we want to see the intermediate values in the method/block chain, we need to insert <code>tap{|e| p e}</code>.</p>
<p>With the above example,</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.tap{|e| p e} # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.tap{|e| p e} # debug print
.yield_self { |id| "server:#{id}" }
</code></pre>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<p>Let <code>obj.p</code> work the same as <code>p(obj)</code>.</p>
<p>We can replace<br>
<code>block{...}.tap{|e| p e}</code><br>
with<br>
<code>block{...}.p</code></p>
<p>For the above example, we can simply add <code>.p</code> at the end of a line:</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.p # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.p # debug print
.yield_self { |id| "server:#{id}" }
</code></pre>
<a name="Compatibility-issues"></a>
<h1 >Compatibility issues<a href="#Compatibility-issues" class="wiki-anchor">¶</a></h1>
<p>(1) Shorthand for <code>nil</code></p>
<p>This spec change can introduce compatibility issues because <code>p</code> returns <code>nil</code> and does not output anything.<br>
That is to say, <code>p</code> is a shorthand for <code>nil</code>. Some code-golfers use it.</p>
<p>Maybe we can ignore them :p</p>
<p>(2) make it a public method</p>
<p><code>Kernel#p</code> a is private method, so if we mistype <code>obj.x</code> as <code>obj.p</code> (not sure how it is feasible), it will raise a <code>NoMethodError</code> because of visibility.<br>
We need to change this behavior.</p>
<a name="Note"></a>
<h1 >Note<a href="#Note" class="wiki-anchor">¶</a></h1>
<a name="Past-proposal-and-discussion"></a>
<h2 >Past proposal and discussion<a href="#Past-proposal-and-discussion" class="wiki-anchor">¶</a></h2>
<p>Endoh-san proposed the same idea 10+ years ago <a href="https://blade.ruby-lang.org/ruby-dev/29736">[ruby-dev:29736]</a> in Japanese.<br>
I think we should revisit this idea because of <code>yield_self</code> introduction.</p>
<p>In this thread, Matz said "simple <code>p</code> shows <code>p(self)</code>, it is not clear".</p>
<p><a href="https://blade.ruby-lang.org/ruby-dev/30903">[ruby-dev:30903]</a></p>
<pre><code> p
はどう動くのかとか(p selfと同じ、は変な気が)
self.p(obj)
はどうなのかとか。その辺が解決(納得)できたら、ということで。
</code></pre>
<p>English translation:</p>
<pre><code>What would the behavior of:
p
be? (I feel strange for it to be equivalent to `p(self)`.) What would happen to
self.p(obj)
</code></pre>
<a name="pp"></a>
<h2 >pp<a href="#pp" class="wiki-anchor">¶</a></h2>
<p>If this proposal is accepted, we also need to change the behavior of <code>pp</code>.</p>
<a name="gems"></a>
<h2 >gems<a href="#gems" class="wiki-anchor">¶</a></h2>
<p><code>tapp</code> method is provided by a gem.<br>
<a href="https://github.com/esminc/tapp" class="external">https://github.com/esminc/tapp</a></p>
<p>I thought about proposing this method in core. But I found that <code>p</code> is shorter than <code>tapp</code>.<br>
A disadvantage is that <code>p</code> is too short and difficult to grep.</p> Ruby master - Feature #14548 (Open): Allow some_array&.[1] to be a valid syntaxhttps://bugs.ruby-lang.org/issues/145482018-02-23T19:59:34Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<p>Currently, Ruby allows accessing an array's index while testing whether the array is not nil with this syntax: <code>my_array&.[](1)</code>. I've always found this awkward but didn't mind about suggesting anything to improve this.</p>
<p>I was just reading about how JavaScript is probably going to support myArray?.[1] and found that it read good enough for me.</p>
<p>So I'd like to propose about the same syntax, replacing ?. with the Ruby equivalent &. instead. How does that look like to you?</p> Ruby master - Feature #14546 (Open): Hash#delete!https://bugs.ruby-lang.org/issues/145462018-02-23T18:52:02Zrringler (Ryan Ringler)
<p>Hash#delete currently returns nil if a given key is not found in the hash. It would be nice to have a way to check that the key was present in the hash. This can be accomplished with with a block, but it would be nice to have some sugar for this.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="c1"># => nil</span>
<span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">key</span><span class="o">|</span> <span class="k">raise</span> <span class="no">KeyError</span><span class="p">,</span> <span class="s2">"key not found </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span> <span class="c1"># => KeyError (key not found: b)</span>
</code></pre>
<p>I'd like to propose a Hash#delete! method:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete!</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="c1"># => 'a'</span>
<span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete!</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="c1"># => KeyError (key not found: :b)</span>
</code></pre> Ruby master - Feature #14397 (Assigned): public, protected and private should return their argume...https://bugs.ruby-lang.org/issues/143972018-01-24T21:27:26Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<p>Matsuda-san suggested me that <code>public</code>, <code>protected</code> and <code>private</code> should return their arguments instead of <code>self</code>,<br>
to write such code:`</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="nb">require</span> <span class="s2">"finalist"</span>
<span class="c1"># see https://github.com/joker1007/finalist</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="kp">extend</span> <span class="no">Finalist</span>
<span class="n">final</span> <span class="kp">private</span> <span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>I believe that it's reasonable request, and also believe that there is no product code which uses the return values of <code>public</code>, <code>protected</code> and <code>private</code>.<br>
Matz, how do you think about this change?<br>
The patch is attached.</p> Ruby master - Feature #14128 (Open): Introduce Hash#delete default valuehttps://bugs.ruby-lang.org/issues/141282017-11-23T14:18:23Zgshutler (Garry Shutler)
<p>Mirror <code>Hash#fetch(key [, default]) → obj</code> with <code>Hash#delete(key [, default]) → obj</code>.</p>
<p>Allows for more concise extraction of a value from a hash with a default.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Currently</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="p">{</span> <span class="mi">10</span> <span class="p">}</span>
<span class="c1"># Becomes</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:a</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</code></pre> Ruby master - Feature #13129 (Assigned): Refinements cannot refine method_missing and respond_to_...https://bugs.ruby-lang.org/issues/131292017-01-14T17:21:59Zmatsuda (Akira Matsuda)ronnie@dio.jp
<p>Refinements with method_missing and respond_to_missing? behaves very strangely.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">C</span><span class="p">;</span> <span class="k">end</span>
<span class="n">using</span> <span class="no">Module</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">x</span><span class="p">()</span> <span class="nb">p</span><span class="ss">:x</span><span class="p">;</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span> <span class="p">?</span> <span class="nb">p</span><span class="p">(</span><span class="ss">:fooo!</span><span class="p">)</span> <span class="p">:</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">respond_to_missing?</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">include_private</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
<span class="p">(</span><span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span><span class="p">)</span> <span class="o">||</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="p">}</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">x</span>
<span class="nb">p</span> <span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">respond_to?</span> <span class="ss">:foo</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">foo</span>
</code></pre>
<p>The script above doesn't respond_to :foo nor run :foo as expected.<br>
Actually, the result differs between ruby versions.</p>
<pre><code>% ruby -v t.rb
ruby 2.5.0dev (2017-01-14 trunk 57328) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f90ca0fb240> (NoMethodError)
% ruby -v t.rb
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f80ae097780> (NoMethodError)
% ruby -v t.rb
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007fd89c83b518> (NoMethodError)
% ruby -v t.rb
ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-darwin15]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin15.0]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin15.6.0]
t.rb:4: warning: Refinements are experimental, and the behavior may change in future versions of Ruby!
:x
false
:fooo!
</code></pre>
<p>What I can tell is that method_missing was broken at somewhere in between 2.2 and 2.3, and respond_to_missing? has never worked correctly.</p> Ruby master - Feature #12543 (Assigned): explicit tail call syntax: foo() then returnhttps://bugs.ruby-lang.org/issues/125432016-07-02T17:24:19Zmame (Yusuke Endoh)mame@ruby-lang.org
<p>How about introducing a new syntax for tail call?</p>
<pre><code>def foo()
foo()
end
foo() #=> stack level too deep
</code></pre>
<pre><code>def bar()
bar() then return
end
bar() #=> infinite loop
</code></pre>
<ul>
<li>no new keyword (cf. <code>goto foo()</code>)</li>
<li>no conflict with any existing syntax</li>
<li>an experimental patch is available (attached)</li>
<li>no shift/reduce nor reduce/reduce conflict in parse.y</li>
</ul>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@ruby-lang.org" class="email">mame@ruby-lang.org</a></p> Ruby master - Feature #12306 (Open): Implement String #blank? #present? and improve #strip and fa...https://bugs.ruby-lang.org/issues/123062016-04-20T23:33:04Zsam.saffron (Sam Saffron)sam.saffron@gmail.com
<p>Time and again there have been rejected feature requests to Ruby core to implement <code>blank</code> and <code>present</code> protocols across all objects as ActiveSupport does. I am fine with this call and think it is fair.</p>
<p>However, for the narrow case of String having <code>#blank?</code> and <code>#present?</code> makes sense.</p>
<ul>
<li>
<p>Provides a natural extension over <code>#strip</code>, <code>#lstrip</code> and <code>#rstrip</code>. <code>(" ".strip.length == 0) == " ".blank?</code></p>
</li>
<li>
<p>Plays nicely with ActiveSupport, providing an efficient implementation in Ruby core: see: <a href="https://github.com/SamSaffron/fast_blank" class="external">https://github.com/SamSaffron/fast_blank</a>, implementing blank efficiently requires a c extension.</p>
</li>
</ul>
<p>However, if this work is to be done, <code>#strip</code> and should probably start dealing with unicode blanks, eg:</p>
<pre><code>irb(main):008:0> [0x3000].pack("U")
=> " "
irb(main):009:0> [0x3000].pack("U").strip.length
=> 1
</code></pre>
<p>So there are 2 questions / feature requests here</p>
<ol>
<li>Can we add blank? and present? to String?</li>
<li>Can we amend strip and family to account for unicode per: <a href="https://github.com/SamSaffron/fast_blank/blob/master/ext/fast_blank/fast_blank.c#L43-L74" class="external">https://github.com/SamSaffron/fast_blank/blob/master/ext/fast_blank/fast_blank.c#L43-L74</a>
</li>
</ol> Ruby master - Feature #12244 (Open): Add a way to `integer - integer % num`https://bugs.ruby-lang.org/issues/122442016-04-02T13:45:33Znaruse (Yui NARUSE)naruse@airemix.jp
<p>We sometimes calculates <code>integer - integer % num</code>.</p>
<p>For example time series events into time partitions, we write code like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">event</span> <span class="c1"># {time: 1459580435, name: "hoge", text: "Rawr!"}</span>
<span class="n">partition</span> <span class="o">=</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">-</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">%</span> <span class="n">num</span>
<span class="n">chunk</span> <span class="o">=</span> <span class="n">get_chunk</span><span class="p">(</span><span class="n">partition</span><span class="p">)</span>
<span class="n">chunk</span><span class="p">.</span><span class="nf">write</span> <span class="n">event</span>
</code></pre>
<p><a href="https://twitter.com/tagomoris/status/715814050534461440" class="external">https://twitter.com/tagomoris/status/715814050534461440</a><br>
<a href="https://twitter.com/tagomoris/status/715814961260457985" class="external">https://twitter.com/tagomoris/status/715814961260457985</a></p>
<p>The name is always issue.<br>
There are some suggestions likes Integer#adjust](<a href="https://twitter.com/cocoatomo/status/716088708655489024" class="external">https://twitter.com/cocoatomo/status/716088708655489024</a>).</p>
<p>kosaki says <a href="https://twitter.com/kosaki55tea/status/716059296186765312" class="external">Excel's FLOOR() function is FLOOR(number, significance)</a>.<br>
Therefore Ruby should be <a href="https://twitter.com/kosaki55tea/status/716106530114768897" class="external">Integer#floor(digits=1, significance: nil)</a>.<br>
<a href="https://twitter.com/kosaki55tea/status/716107516409581568" class="external">kosaki agrees this</a>.</p>
<p>I checked the speed of a half baked implementation..., but it's 10x slow...</p>
<pre><code>% time ./miniruby -e'i=10000000;while i>0;i-=1;1459497599.floor(significance: 3600);end'
./miniruby 6.58s user 0.02s system 99% cpu 6.596 total
#3 1459604131 22:35:31 naruse@windy:~/obj/ruby
% time ./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end'
./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end' 0.52s user 0.00s system 99% cpu 0.520 total
</code></pre>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/numeric.c b/numeric.c
index 37217a1..f6acfe3 100644
</span><span class="gd">--- a/numeric.c
</span><span class="gi">+++ b/numeric.c
</span><span class="p">@@ -4123,6 +4123,42 @@</span> int_dotimes(VALUE num)
<span class="err">
</span> /*
* call-seq:
<span class="gi">+ * int.floor([ndigits]) -> integer or float
+ *
+ * Rounds +int+ to a given precision in decimal digits (default 0 digits).
+ *
+ * Precision may be negative. Returns a floating point number when +ndigits+
+ * is positive, +self+ for zero, and round down for negative.
+ *
+ * 1.round #=> 1
+ * 1.round(2) #=> 1.0
+ * 15.round(-1) #=> 20
+ */
+
+static VALUE
+int_floor(int argc, VALUE* argv, VALUE num)
+{
+ static ID keyword_ids[1];
+ VALUE kwargs[1], ndigits, opt;
+ if (!keyword_ids[0]) {
+ CONST_ID(keyword_ids[0], "significance");
+ }
+
+ rb_scan_args(argc, argv, "01:", &ndigits, &opt);
+ if (!NIL_P(opt)) {
+ VALUE factor;
+ long a, b;
+ rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs);
+ factor = kwargs[0];
+ a = FIX2LONG(num);
+ b = FIX2LONG(factor);
+ return LONG2FIX(a - a % b);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
</span> * int.round([ndigits]) -> integer or float
*
* Rounds +int+ to a given precision in decimal digits (default 0 digits).
<span class="p">@@ -4321,7 +4357,7 @@</span> Init_Numeric(void)
rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
rb_define_method(rb_cInteger, "to_f", int_to_f, 0);
<span class="gd">- rb_define_method(rb_cInteger, "floor", int_to_i, 0);
</span><span class="gi">+ rb_define_method(rb_cInteger, "floor", int_floor, -1);
</span> rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
rb_define_method(rb_cInteger, "round", int_round, -1);
</code></pre> Ruby master - Feature #12019 (Open): Better low-level support for writing concurrent librarieshttps://bugs.ruby-lang.org/issues/120192016-01-25T19:16:25Zpitr.ch (Petr Chalupa)
<p>Nowadays, almost every processor has more than one core. Therefore it becomes more and more important for languages to have good support of concurrent and/or parallel computation. Currently Ruby supports concurrency mainly through high-level classes: <code>Thread</code>, <code>Queue</code>, <code>Mutex</code>, <code>Monitor</code>, <code>ConditionVariable</code>.</p>
<p>This work is not colliding with plans for Ruby 3 (to provide an easy-to-use and safe concurrent abstraction to Ruby users). Following proposals suggest several key low-level Ruby extensions which will allow those interested in these topics to create fast concurrency abstractions (gems) for Ruby community, providing more choices and complementing the effort of Ruby 3. The proposed APIs are not expected to be used for every day programming but rather by concurrency enthusiast.</p>
<p>This issue is intended to serve as an aggregator for other various proposals described in following issues.</p> Ruby master - Feature #11882 (Open): Map or NamedMaphttps://bugs.ruby-lang.org/issues/118822015-12-26T20:28:30Zhcatlin (Hampton Catlin)hcatlin@gmail.com
<p>Hash is one of the best features of Ruby. I remember being so pleased when I first learned Ruby to find out that <em>anything</em> could be a key and that you could do some really clever things with scripts, if you key of non-traditional elements.</p>
<p>However, like many people, 10 years into using Ruby, I still am writing code to cast around symbols to strings and strings to symbols, just to use Hash as a more traditional dictionary, keyed with string-like values. And, explaining to a junior programmers why they broke the code by using a key of a different type... it's not the most elegant thing to have to explain over and over.</p>
<p>Several proposals exist for how to deal with this, and all have been rejected... however it doesn't seem like it's for essential reasons, more technical or syntactic issues. Coming up with syntax is something I quite enjoy (Sass/Haml), so I thought I'd make a pitch for it.</p>
<p>Requirements:</p>
<ol>
<li>Doesn't break existing code</li>
<li>Doesn't totally destroy the parser</li>
<li>Seems simple to differentiate</li>
<li>Clear upgrade path</li>
</ol>
<p>My proposal is to introduce an entirely different type of Hash, called a Map (or NamedMap, if that's too ambiguous), that requires a string-like key. There are no other types of keys allowed on this Hash, other than either strings or symbols. Internally, each key would be considered a symbol only.</p>
<pre><code>map = Map.new(a: 2, b: 3)
map["a"] #=> 2
map[:a] #=> 2
</code></pre>
<p>Already, we're better than HashWithIndifferentAccess, as it's clearly a bit easier to type. ;)</p>
<p>What about a literal syntax?</p>
<pre><code>map = {{a: 2}}
empty_map = {{}}
</code></pre>
<p>As far as I can tell in the Ruby-syntax style, this should be pretty easy to distinguish syntactically from both a regular hash literal and a block. Further, as almost every method's option hash is string-keyed, you could easily define this.</p>
<pre><code>def my _method(arg1, options = {{}})
end
</code></pre>
<p>Immediately, you could deal with your options hash, and not have to stress about if the end user has passed in strings or symbols into the options.</p>
<p>It would be trivial to create a Map polyfill for most libraries to start using the non-literal version right away, as it would basically be HashWithIndifferentAccess, except we need to guarantee that the keys are string-like.</p>
<p>So, to sum up, we avoid the 'breaking other people's existing code' by introducing a new data-type, the literal syntax (I think) should be fairly easy to implement, and it makes a very natural keyed data object (e.g. Javascript Objects) and brings that to Ruby.</p> Ruby master - Feature #11816 (Assigned): Partial safe navigation operatorhttps://bugs.ruby-lang.org/issues/118162015-12-14T18:19:37Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I'm extremely surprised (and disappointed) that, currently:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">x</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">x</span><span class="o">&</span><span class="p">.</span><span class="nf">foo</span><span class="p">.</span><span class="nf">bar</span> <span class="c1"># => NoMethodError: undefined method `bar' for nil:NilClass</span>
</code></pre>
<p>To make it safe, you have to write <code>x&.foo&.bar</code>. But if <code>foo</code> is never supposed to return <code>nil</code>, then that code isn't "fail early" in case it actually does. <code>nil&.foo.bar</code> is more expressive, simpler and is perfect if you want to an error if <code>foo</code> returned <code>nil</code>. To actually get what you want, you have to resort using the old form <code>x && x.foo.bar</code>...</p>
<p>In CoffeeScript, you can write <code>x()?.foo.bar</code> and it will work well, since it gets compiled to</p>
<pre><code class="js syntaxhl" data-language="js"><span class="k">if </span><span class="p">((</span><span class="nx">_ref</span> <span class="o">=</span> <span class="nf">x</span><span class="p">())</span> <span class="o">!=</span> <span class="kc">null</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">_ref</span><span class="p">.</span><span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span><span class="p">;</span>
<span class="p">}</span>
</code></pre>
<p>All the discussion in <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Introduce "Safe navigation operator" (Closed)" href="https://bugs.ruby-lang.org/issues/11537">#11537</a> focuses on <code>x&.foo&.bar</code>, so I have to ask:</p>
<p>Matz, what is your understanding of <code>x&.foo.bar</code>?</p>
<p>I feel the current implementation is not useful and should be changed to what I had in mind. I can't see any legitimate use of <code>x&.foo.bar</code> currently.</p> Ruby master - Feature #11735 (Open): Porting String#squish and String#squish! from Ruby on Rails'...https://bugs.ruby-lang.org/issues/117352015-11-24T19:36:33Zsikachu (Prem Sichanugrist)s+ruby@sikac.hu
<p>Hi,</p>
<p>I have been using this <code>String#squish</code> method so many time when I'm using Rails, and I think it should be a useful addition to core.</p>
<p>Here's the method on Rails' documentation: <a href="http://api.rubyonrails.org/v4.2.5/classes/String.html#method-i-squish" class="external">http://api.rubyonrails.org/v4.2.5/classes/String.html#method-i-squish</a></p>
<p>This method is very useful when you have to write a multi-line string using heredoc, but you actually does not care about the white-spaces before, after, and in-between the string.</p>
<p>For example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="o"><<-</span><span class="no">SQL</span><span class="p">.</span><span class="nf">squish</span><span class="sh">
SELECT *
FROM users
WHERE users.username = 'sikachu'
</span><span class="no">SQL</span>
<span class="c1">#=> "SELECT * FROM users WHERE users.username='sikachu'"</span>
</code></pre>
<p>Another example usage is when you are on the project that have a line length code standard, and you have to write a long warning message that needs to be printed to stdout:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">puts</span> <span class="o"><<-</span><span class="no">WARNING</span><span class="p">.</span><span class="nf">squish</span><span class="sh">
Unable to connect to the server. Please double-check that you are currently
connecting to the internet and your proxy server is working.
</span><span class="no">WARNING</span>
<span class="c1">#=> Unable to connect to the server. Please double-check that you are currently connecting to the internet and your proxy server is working.</span>
</code></pre>
<p>By the way, this is my first patch and my first time writing something in C, so there might be something that does not look right to you. I'll happy to revise this patch (and learn about C in the process!) from your feedback.</p>
<p>Thank you,<br>
Prem</p> Ruby master - Feature #11627 (Open): make `nonzero` an alias of `nonzero?`https://bugs.ruby-lang.org/issues/116272015-10-27T23:00:34ZAnonymous
<p>for historic reasons <code>nonzero?</code> returns self or nil. (according to <a href="https://bugs.ruby-lang.org/issues/9123" class="external">https://bugs.ruby-lang.org/issues/9123</a>)</p>
<p>I like the expectation that <code>method?</code> returns true and false.<br>
That <code>nonzero?</code> returns only truthy/falsy values would be fine, except using its return values are <em>useful</em>.</p>
<p><code>value.nonzero? || calculation</code> or <code>(a <=> b).nonzero? || a.subvalue <=> b.subvalue</code></p>
<p>I would feel more comfortable with <code>value.nonzero || calculation</code> even though it is only one character different.</p>
<p>Yes, it's a small thing, but I like ruby for the small things :)</p>
<p>Thanks.</p> Ruby master - Feature #11518 (Open): Queue enhancement - promote! and promote_all!https://bugs.ruby-lang.org/issues/115182015-09-09T15:04:58Zjonathanscruz (Jonathan Cruz)jonathanscruz@yahoo.com
<p>I’m submitting a patch to enhance the Queue class by adding the methods Queue#promote! and Queue#promote_all!. These methods require a block that accepts queue elements. Elements for which the block returns a truthy value are moved to the ‘front’ of the queue. Queue#promote! only applies to the first such element and Queue#promote_all! applies to all matching elements (preserving their relative order).</p>
<p>Motivation for this enhancement: Our project has several worker threads working on long-running work units in a queue, trying to find a ‘match’. The queue is pre-sorted with the most likely matches at the front and least likely at the back. However, there are cases where as we work on some elements, we gain new data that certain elements are more likely to match than we originally thought. We need a way to promote these elements to the front of the queue.</p> Ruby master - Feature #11517 (Open): Queue enhancement - conditional pophttps://bugs.ruby-lang.org/issues/115172015-09-09T15:03:32Zjonathanscruz (Jonathan Cruz)jonathanscruz@yahoo.com
<p>I’m submitting a patch to enhance Queue#pop. This allows the caller to provide a block that accepts data from the queue. Queue#pop will return the first element for which the block returns a truthy value, and remove it from the queue. Without a block, Queue#pop will behave the same way it currently does.</p>
<p>The motivation for this enhancement: On our project, we have a queue of work and several worker threads. Some work can incur a heavy load on the system and should not be processed while another worker is processing 'heavy load' work. We need a way for Queue#pop to skip over heavy load items while another thread is processing heavy load work.</p> Ruby master - Feature #11390 (Open): Allow symbols starting with numbershttps://bugs.ruby-lang.org/issues/113902015-07-22T19:32:50Zv0dro (Sameer Deshmukh)sameer.deshmukh93@gmail.com
<p>Currently it is not possible to create a symbol that looks like <code>:1twothree</code>.</p>
<p>Converting to a string and then symbolizing causes hash lookup problems and proves counter-intuitive. What's also surprising is that ruby allows symbols to start with special characters but not numbers.</p> Ruby master - Feature #11307 (Open): exception-free non-blocking Queue#pophttps://bugs.ruby-lang.org/issues/113072015-06-25T23:06:21Znormalperson (Eric Wong)normalperson@yhbt.net
<p>As we learned from the nonblocking IO APIs, exceptions are noisy with debugging<br>
enabled and waste allocations on backtraces. We should have a better way to do<br>
non-blocking Queue#pop without raising exceptions, but I don't know what the API<br>
should be...</p> Ruby master - Feature #11181 (Open): Add a line directive to Rubyhttps://bugs.ruby-lang.org/issues/111812015-05-26T07:05:18Zgam3 (Allen Morris)gam3-ruby@gam3.net
<p>Add a <strong>line directive</strong> to Ruby</p>
<pre><code> #line {nn} ["filename"]
</code></pre>
<p>This is done by creating a array of filenames and using the upper bits of the line_number to determine the current filename. The original filename is in position 0.</p>
<p>An extra node is added by the parser that informs the compiler of the filenames so the backtrace code can also use the correct file names.</p>
<p>The <strong>__LINE</strong>__ and <strong>__FILE</strong>__ <em>constants</em> are updated and compile time warnings are also effected.</p>
<p>There is a pull request at <a href="https://github.com/ruby/ruby/pull/911" class="external">https://github.com/ruby/ruby/pull/911</a></p>
<p>The patch does not have any affect on current programs unless a line matching '#\s<em>line \d+(\s+"(.</em>)")?\s*$' is found in the ruby source code.</p>
<p>More tests need to be written before this change sould be applied.</p>
<p>Use case:</p>
<p>This is helpful for debugging any generated code but is particularlly helpful for literate programming using Noweb.</p> Ruby master - Feature #11122 (Open): exception-free non-blocking Queue/SizedQueue operationshttps://bugs.ruby-lang.org/issues/111222015-05-06T20:53:09Znormalperson (Eric Wong)normalperson@yhbt.net
<p>I would like to reduce exceptions for non-blocking operations on<br>
Queue/SizedQueue in the same way we are reducing exceptions for non-blocking<br>
I/O with *_nonblock(..., exception: false) methods.</p>
<p>However, I'm unclear what the API would be, since queues return Ruby objects<br>
instead of String buffers or number of bytes written, so any special<br>
object/symbol we would return could conflict with existing applications.</p>
<p>Perhaps something like:</p>
<pre><code>queue.pop(nonblock: :WAIT)
queue.push(obj, nonblock: :WAIT)
</code></pre>
<p>Which would allow user to specify which object to raise when a queue is empty<br>
or full (similar to Timeout.timeout allowing specific exception to raise).</p> Ruby master - Feature #11028 (Assigned): standalone running single file ( zipped archives of ruby...https://bugs.ruby-lang.org/issues/110282015-04-03T03:44:09Zzaxebo1 (zaxebo zaxebo)zaxebo1@gmail.com
<p>standalone running single file ( zipped archives of ruby code) running <strong>without installation</strong> using "gem install ..."<br>
prior examples in other languages:</p>
<pre><code>python myprg.pyz
java -jar myprg.jar
</code></pre>
<a name="Detailed-Description"></a>
<h2 >Detailed Description:<a href="#Detailed-Description" class="wiki-anchor">¶</a></h2>
<p>In python, if i have multiple program files: "<code>a1.py</code>, <code>a2.py</code>, <code>__main__.py</code>,<br>
<code>dir1/b1.py</code>, <code>dir1/b2.py</code>" and then i zip it as myprogram1.pyz<br>
then i can run it as "python myprogram.pyz" (<code>__main__.py</code> inside the zip<br>
file will be executed first). It is easy to distribute a single file<br>
myprogram1.pyz</p>
<p>see: <a href="http://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/" class="external">http://blogs.gnome.org/jamesh/2012/05/21/python-zip-files/</a></p>
<hr>
<p>in java also we can bundle all the .class files into a single .jar file<br>
and run it</p>
<pre><code>java -jar myprogram1.jar
</code></pre>
<hr>
<p>Currently in ruby the ".gem" file requires installation using "gem install ...". Then it gives some program file for running.<br>
What i am asking is that some gem file should have manifest with which they can run directly without installing</p>
<p>That is, i request you to kind provide a feature in ruby that if i have lots of files like: <code>a1.rb</code>, <code>a2.rb</code>, <code>__main__.rb</code>, <code>dir1/a4.rb</code> etc.<br>
(say, which uses Ruby-GTK for a Desktop application). Then i should be able to bundle them as zip file, say myprog1.zip or myprog1.pz ( rbz=ruby's zipped executable archive).<br>
And then i can distribute this "single file" and execute it as:</p>
<pre><code>ruby myprog1.rbz
</code></pre>
<p>This will execute the <code>__main__.rb</code> file among all the other .rb files,<br>
inside this .zip archive myprog1.rbz .<br>
Note: this .rbz file extension can be .gemz or whatever, but this functionality of "standalone running zipped archives of ruby code running without installation" is essential</p> Ruby master - Feature #10574 (Open): Add String#lchomp and String.lchomp!https://bugs.ruby-lang.org/issues/105742014-12-05T20:37:41Zjavawizard (Alex Boyd)alex@opengroove.org
<p>With the expected behavior, i.e.</p>
<pre><code>irb(main):013:0> 'foobar'.lchomp('foo')
=> "bar"
irb(main):014:0> 'foobar'.lchomp('baz')
=> "foobar"
</code></pre>
<p>A quick google search will turn up plenty of practical uses for this, as well as lots of libraries that patch <code>String</code> themselves to add this.</p> Ruby master - Feature #10549 (Open): Deprecate each_with_index and each_with_object in favor of w...https://bugs.ruby-lang.org/issues/105492014-11-26T16:12:04Zdanielmorrison (Daniel Morrison)daniel@collectiveidea.com
<p>I wonder if we can deprecate <code>each_with_index</code> and <code>each_with_object</code> and fully recommend <code>with_index</code> and <code>with_object</code> instead.</p>
<p>I personally like the shorter forms because they hint that they can be used with more methods than simply <code>each</code>. People don't need to ask if there's a <code>map_with_index</code> method, they can just try chaining it the same way and it works! I realized this when teaching new Rubyists, because they often ask those questions.</p>
<p>There is a negligible performance hit.</p>
<p>Lots of code uses <code>each_with_index</code> but it is a one-character change to use <code>each.with_index</code> instead.</p>
<p>Forgive me if this has been brought up recently, but I couldn't find any discussion on it.</p> Ruby master - Misc #10541 (Open): Remove shorthand string interpolation syntaxhttps://bugs.ruby-lang.org/issues/105412014-11-25T16:15:58Zdanielmorrison (Daniel Morrison)daniel@collectiveidea.com
<p>I would like to see the shorthand string interpolation syntax, "foo#@bar" deprecated and then removed in 3.0.</p>
<p>My reasons:</p>
<ol>
<li>Most experienced Ruby developers I've talked to don't even know it exists.</li>
<li>It has been the cause of real problems. <a href="http://status.cloudamqp.com/incidents/vj62pnp62tj9" class="external">http://status.cloudamqp.com/incidents/vj62pnp62tj9</a>
</li>
</ol>
<p>When a syntax is not widely known and has the potential for problems, I think it makes sense to deprecate and remove.</p> Ruby master - Feature #10498 (Open): Make `loop` yield a counterhttps://bugs.ruby-lang.org/issues/104982014-11-12T06:33:46Zcesario (Franck Verrot)franck@verrot.fr
<a name="Problem"></a>
<h1 >Problem<a href="#Problem" class="wiki-anchor">¶</a></h1>
<p>Teaching Ruby, we always end up with that type of construct</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="c1"># do something with i....</span>
<span class="k">raise</span> <span class="no">StopIteration</span> <span class="k">if</span> <span class="n">i</span> <span class="o">...</span>
<span class="k">end</span>
</code></pre>
<a name="Solution"></a>
<h1 >Solution<a href="#Solution" class="wiki-anchor">¶</a></h1>
<p>What I propose with this patch is making <code>loop</code> yield the iteration count:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="kp">loop</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="c1"># do something with i....</span>
<span class="k">raise</span> <span class="no">StopIteration</span> <span class="k">if</span> <span class="n">i</span> <span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p><code>i</code> starts at 0 and stops at <code>FIXNUM_MAX</code> (there's no <code>Float::Infinity</code> equivalent for integers).</p>
<a name="Alternate-solution"></a>
<h1 >Alternate solution<a href="#Alternate-solution" class="wiki-anchor">¶</a></h1>
<p><code>Integer#times</code> could work if we had an <code><Integer's infinity></code> object, so we would just do <code><Integer's Infinity>.times { |i| ... }</code>.</p>
<p>Also, this is the very first patch I submit to Ruby, I might have done something horrible, feel free to tell me :-)</p> Ruby master - Feature #10489 (Open): Add inherit method for clearer and multiple inheritancehttps://bugs.ruby-lang.org/issues/104892014-11-09T01:57:19Zbrauliobo (Bráulio Bhavamitra)brauliobo@gmail.com
<p>A new and more intuitive syntax:</p>
<pre><code>class B
end
class A
inherit B
end
</code></pre>
<p>Instead of (but keeping this for backwards compatibility):</p>
<pre><code>class B
end
class A < B
end
</code></pre>
<p>Besides, this allows multiple inheritance. Also, <code>inherit</code> could be implemented with just <code>extend</code> plus <code>include</code>?</p> Ruby master - Feature #10481 (Assigned): Add "if" and "unless" clauses to rescue statementshttps://bugs.ruby-lang.org/issues/104812014-11-05T19:20:10Zjavawizard (Alex Boyd)alex@opengroove.org
<p>I'd like to propose a syntax change: allow boolean "if" and "unless" clauses to follow a rescue statement.</p>
<p>Consider the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span>
<span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">else</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>This is a fairly common way of dealing with exceptions where some condition above and beyond the exception's type determines whether the exception should be rescued. It's verbose, though, and it's not obvious at first glance exactly what conditions are being rescued, especially if "...handle error..." is more than a few lines long. I propose that the following be allowed:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>"unless" would, of course, be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">unless</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>A rescue statement whose boolean condition failed would be treated the same as if the exception being raised didn't match the exception being rescued, and move on to the next rescue statement:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">1</span><span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">2</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>And finally, catch-all rescue statements would be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span> <span class="o">==</span> <span class="s2">"some error"</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #10404 (Open): Allow individual finalizers to be removed with ObjectSpace.u...https://bugs.ruby-lang.org/issues/104042014-10-20T08:14:36Zjavawizard (Alex Boyd)alex@opengroove.org
<p>Pretty self-explanatory: allow removal of individual define_finalizer blocks without removing all of them as undefine_finalizer currently does.</p>
<p>From an API standpoint, this could be done by having define_finalizer return some sort of unique value (maybe an integer, or perhaps the type is unspecified), and this value could then be passed as undefine_finalizer's second argument to remove just that finalizer.</p> Ruby master - Feature #10287 (Open): rename COLON3 to COLON2_HEAD.https://bugs.ruby-lang.org/issues/102872014-09-23T16:15:00Zarimay (yasuhiro arima)
<p>主に parse.y を読んでいて、DOT2 に対する DOT3 はわかるのですが、COLON2 に対する COLON3 はよくない名前だと思いました。<br>
COLON3 の表すものは ::FOO::BAR のようにスコープ指定の先頭を表すものなので、COLON2_HEAD としてパッチを作ってみました。</p> Ruby master - Feature #9816 (Assigned): 文字列内の数字を数値として比較するメソッドhttps://bugs.ruby-lang.org/issues/98162014-05-08T09:37:26Znaruse (Yui NARUSE)naruse@airemix.jp
<p>文字列内の数字を数値として比較するメソッドを追加しませんか</p>
<p>そのような比較は一般的な用途としてはGUIシェルのファイラーが比較に用いており、<br>
Windows では StrCmpLogicalW が、OS X では NSString:compare:options:へのNSNumericSearch定数が提供されています。<br>
<a href="http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx" class="external">http://msdn.microsoft.com/en-us/library/windows/desktop/bb759947(v=vs.85).aspx</a><br>
<a href="https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch" class="external">https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/c/econst/NSNumericSearch</a></p>
<p>上記のような処理自体はさほど難しいものではありませんが、Rubyレベルで実装すると大量のオブジェクトを作ってしまいます。<br>
例えば <code>Gem::Version.new("2.1.10".freeze)<=>Gem::Version.new("2.1.9".freeze)</code> は47個、<br>
<code>"2.1.10".freeze.split('.').map(&:to_i)<=>"2.1.9".freeze.split('.').map(&:to_i)</code> だと16個のオブジェクトを作ります。<br>
<code>"2.1.10".freeze.numericcmp"2.1.9".freeze</code> ならば、もちろんオブジェクトは一つも作りません。</p>
<p>なお、上記の例でも示唆していますが、本メソッドは Ruby のバージョン表記の TEENY が2桁になった場合の比較に用いることができます。</p>
<p>パッチは以下の通りです。<br>
なお、メソッド名は String#numericcmp としています。<br>
(String#casecmpを念頭に置いた)</p>
<pre><code>diff --git a/string.c b/string.c
index c589c80..66f667f 100644
--- a/string.c
+++ b/string.c
@@ -2569,6 +2569,131 @@ rb_str_casecmp(VALUE str1, VALUE str2)
return INT2FIX(-1);
}
+VALUE
+numerical_compare(const char **pp1, const char *p1end, const char **pp2, const char *p2end)
+{
+ const char *s1 = *pp1, *p1, *s2 = *pp2, *p2;
+ ptrdiff_t len1, len2;
+ int r;
+
+ while (s1 < p1end && *s1 == '0') s1++;
+ p1 = s1;
+ while (p1 < p1end && ISDIGIT(*p1)) p1++;
+ len1 = p1 - s1;
+
+ while (s2 < p2end && *s2 == '0') s2++;
+ p2 = s2;
+ while (p2 < p2end && ISDIGIT(*p2)) p2++;
+ len2 = p2 - s2;
+
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ r = memcmp(s1, s2, len1);
+ if (r) return r < 0 ? INT2FIX(-1) : INT2FIX(1);
+
+ len1 = s1 - *pp1;
+ len2 = s2 - *pp2;
+ if (len1 != len2) {
+ return INT2FIX(len1 < len2 ? -1 : 1);
+ }
+
+ *pp1 = p1;
+ *pp2 = p2;
+ return Qnil;
+}
+
+/*
+ * call-seq:
+ * str.numericcmp(other_str) -> -1, 0, +1 or nil
+ *
+ * Variant of <code>String#<=></code>, which considers digits in strings
+ * are numeric value..
+ *
+ * "a1".numericcmp("a1") #=> 0
+ * "aa".numericcmp("a1") #=> 1
+ * "a1".numericcmp("aa") #=> -1
+ * "a1".numericcmp("a01") #=> -1
+ * "2.1.2".numericcmp("2.1.10") #=> 1
+ */
+
+static VALUE
+rb_str_numericcmp(VALUE str1, VALUE str2)
+{
+ long len;
+ rb_encoding *enc;
+ const char *p1, *p1end, *p2, *p2end;
+
+ StringValue(str2);
+ enc = rb_enc_compatible(str1, str2);
+ if (!enc) {
+ return Qnil;
+ }
+
+ p1 = RSTRING_PTR(str1); p1end = RSTRING_END(str1);
+ p2 = RSTRING_PTR(str2); p2end = RSTRING_END(str2);
+ if (single_byte_optimizable(str1) && single_byte_optimizable(str2)) {
+ while (p1 < p1end && p2 < p2end) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ }
+ else {
+ while (p1 < p1end && p2 < p2end) {
+ int l1, c1 = rb_enc_ascget(p1, p1end, &l1, enc);
+ int l2, c2 = rb_enc_ascget(p2, p2end, &l2, enc);
+
+ if (0 <= c1 && 0 <= c2) {
+ if (ISDIGIT(*p1)) {
+ if (ISDIGIT(*p2)) {
+ VALUE r = numerical_compare(&p1, p1end, &p2, p2end);
+ if (!NIL_P(r)) return r;
+ }
+ else {
+ return INT2FIX(-1);
+ }
+ }
+ else if (ISDIGIT(*p2)) {
+ return INT2FIX(1);
+ }
+ if (*p1 != *p2) return INT2FIX(*p1 < *p2 ? -1 : 1);
+ p1++;
+ p2++;
+ }
+ else {
+ int r;
+ l1 = rb_enc_mbclen(p1, p1end, enc);
+ l2 = rb_enc_mbclen(p2, p2end, enc);
+ len = l1 < l2 ? l1 : l2;
+ r = memcmp(p1, p2, len);
+ if (r != 0)
+ return INT2FIX(r < 0 ? -1 : 1);
+ if (l1 != l2)
+ return INT2FIX(l1 < l2 ? -1 : 1);
+ }
+ p1 += l1;
+ p2 += l2;
+ }
+ }
+ if (RSTRING_LEN(str1) == RSTRING_LEN(str2)) return INT2FIX(0);
+ if (RSTRING_LEN(str1) > RSTRING_LEN(str2)) return INT2FIX(1);
+ return INT2FIX(-1);
+}
+
static long
rb_str_index(VALUE str, VALUE sub, long offset)
{
@@ -8721,6 +8846,7 @@ Init_String(void)
rb_define_method(rb_cString, "eql?", rb_str_eql, 1);
rb_define_method(rb_cString, "hash", rb_str_hash_m, 0);
rb_define_method(rb_cString, "casecmp", rb_str_casecmp, 1);
+ rb_define_method(rb_cString, "numericcmp", rb_str_numericcmp, 1);
rb_define_method(rb_cString, "+", rb_str_plus, 1);
rb_define_method(rb_cString, "*", rb_str_times, 1);
rb_define_method(rb_cString, "%", rb_str_format_m, 1);
diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb
index 8366424..f9c788b 100644
--- a/test/ruby/test_string.rb
+++ b/test/ruby/test_string.rb
@@ -2104,6 +2104,29 @@ class TestString < Test::Unit::TestCase
assert_equal(1, "\u3042B".casecmp("\u3042a"))
end
+ def test_numericcmp
+ assert_equal(-1, "2.1.0".numericcmp("2.1.1"))
+ assert_equal(-1, "2.1.9".numericcmp("2.1.10"))
+ assert_equal( 0, "a1".numericcmp("a1"))
+ assert_equal( 1, "aa".numericcmp("a1"))
+ assert_equal(-1, "a1".numericcmp("aa"))
+ assert_equal(-1, "a1".numericcmp("a01"))
+ assert_equal(-1, "a0001".numericcmp("a00001"))
+ assert_equal( 0, "a1a".numericcmp("a1a"))
+ assert_equal( 1, "a1b".numericcmp("a1a"))
+ assert_equal(-1, "a9a".numericcmp("a10a"))
+ assert_equal( 1, "b".numericcmp("a"))
+ assert_equal( 0, "\u30421".numericcmp("\u30421"))
+ assert_equal( 1, "\u3042\u3042".numericcmp("\u30421"))
+ assert_equal(-1, "\u30421".numericcmp("\u3042\u3042"))
+ assert_equal(-1, "\u30421".numericcmp("\u304201"))
+ assert_equal(-1, "\u30420001".numericcmp("\u304200001"))
+ assert_equal( 0, "\u30421\u3042".numericcmp("\u30421\u3042"))
+ assert_equal( 1, "\u30421\u3044".numericcmp("\u30421\u3042"))
+ assert_equal(-1, "\u30429\u3042".numericcmp("\u304210\u3042"))
+ assert_equal( 1, "\u3044".numericcmp("\u3042"))
+ end
+
def test_upcase2
assert_equal("\u3042AB", "\u3042aB".upcase)
end
</code></pre> Ruby master - Feature #9768 (Assigned): Method that is visible only within a certain module/classhttps://bugs.ruby-lang.org/issues/97682014-04-22T09:57:35Zsawa (Tsuyoshi Sawada)
<p>Some frameworks/libraries monkeypatch their own methods on Ruby core classes like <code>String</code>, <code>Hash</code>, <code>Array</code>, etc., and that is often causing problems/concerns of name conflict.</p>
<p>Seeing that these custom methods are used only in the context of a certain module/class, I request for a way to define a method (<code>foo</code>) on a module/class (<code>A</code>) so that it will be visible only from within a specified module/class (<code>B</code>) or its descendants. The following illustrates this situation:</p>
<pre><code>A.new.foo # => undefined
class B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
class C < B
A.new.foo # => defined
def bar
A.new.foo # => defined
end
def self.baz
A.new.foo # => defined
end
end
</code></pre>
<p>I do not have a certain syntax for this in mind, but I think it can be made much simpler, compared to the complicated syntax of refinement.</p>
<p>This is reminiscent of refinement, but they are pretty much different.</p>
<p>Refinement's purpose is to let certain methods be accessible from only a certain file. A typical use case would be a library developer defining their methods to be used from within the library and making such methods inaccessible from the end user.</p>
<p>On the other hand, the idea I am proposing here is for making method accessible from any file, but only within a certain module/class. A typical use case would be defining a method to be used by an end user, but only from within a context of certain module/class.</p> Ruby master - Feature #9704 (Open): Refinements as files instead of moduleshttps://bugs.ruby-lang.org/issues/97042014-04-04T20:41:06Ztrans (Thomas Sawyer)
<p>If refinements are to remain file-scoped, then it would be more convenient if <code>using</code> worked at the file level, akin to <code>require</code>, rather than behave like a module <code>include</code>. For instance, instead of:</p>
<pre><code># foo.rb
module Foo
refine String do
def some_method
...
end
end
end
</code></pre>
<pre><code>require 'foo'
using Foo
</code></pre>
<p>We could do:</p>
<pre><code># foo.rb
class String
def some_method
...
end
end
</code></pre>
<pre><code>using 'foo'
</code></pre>
<p>This would make <code>require</code> and <code>using</code>, in a certain sense, <em>polymorphic</em> --if we <code>require</code> it will extend the classes directly, but if <code>using</code> then they will be refined instead.</p> Ruby master - Feature #9614 (Open): ordering of non-Hash items which use st_ internallyhttps://bugs.ruby-lang.org/issues/96142014-03-09T02:25:28Znormalperson (Eric Wong)normalperson@yhbt.net
<p>Hi matz, I would like your permission to remove the order preservation from<br>
any or all of the following currently implemented using <code>st_table</code>:</p>
<ul>
<li>method tables</li>
<li>global symbols (<code>Symbol.all_symbols</code>)</li>
<li>constant tables</li>
<li>instance variable tables</li>
<li>
<code>global_variables</code> method</li>
<li><code>Thread#keys</code></li>
<li>anything besides the <code>Hash</code> class</li>
</ul>
<p>I am currently working on a patch series to reduce internal memory usage,<br>
so far I have only converted three pieces:</p>
<ol>
<li>method tables (~200K reduction)</li>
<li>symbol table (<code>global_symbols.</code>{<code>id_str</code>,<code>sym_id</code>}) (~200K)</li>
<li>
<code>frozen_strings</code> (~100K)</li>
</ol>
<p>n.b. <code>frozen_strings</code> ordering is never exposed to users, so I expect<br>
it to be OK.</p>
<p>Memory reduction is just based on "<code>ruby -e exit</code>" (which loads RubyGems);<br>
bigger programs with more methods/symbols will save more memory.</p>
<p>Work-in-progress patches attached (0002 describes implementation details)</p> Ruby master - Feature #9123 (Open): Make Numeric#nonzero? behavior consistent with Numeric#zero?https://bugs.ruby-lang.org/issues/91232013-11-19T03:12:47Zsferik (Erik Michaels-Ober)sferik@gmail.com
<p>Numeric#zero? returns true or false, while Numeric#nonzero? returns self or nil.</p>
<p>I've written a patch that fixes this inconsistency and adds a Numeric#nonzero (non-predicate) method that returns self or nil for chaining comparisons. I'd like for this to be included in Ruby 2.1.0.</p>
<p><a href="https://github.com/ruby/ruby/pull/452.patch" class="external">https://github.com/ruby/ruby/pull/452.patch</a></p> Ruby master - Feature #9070 (Open): Introduce `---` as synonym of `end` keywordhttps://bugs.ruby-lang.org/issues/90702013-11-01T23:17:58Zalexeymuranov (Alexey Muranov)
<p>=begin<br>
This is just an idea: introduce "(({---}))" as synonym of "(({end}))" keyword.</p>
<p>It is a bit easier to type and to read, and makes whitespace insensitive language look as if it follows off-side rule. Compare:</p>
<h2>class Person<br>
attr_reader :name, :age<br>
def initialize(name, age)<br>
@name, @age = name, age<br>
---<br>
def <=>(person) # the comparison operator for sorting<br>
age <=> person.age<br>
---<br>
def to_s<br>
"#{name} (#{age})"<br>
---</h2>
<p>class Person<br>
attr_reader :name, :age<br>
def initialize(name, age)<br>
@name, @age = name, age<br>
end<br>
def <=>(person) # the comparison operator for sorting<br>
age <=> person.age<br>
end<br>
def to_s<br>
"#{name} (#{age})"<br>
end<br>
end</p>
<p>=end</p> Ruby master - Feature #9043 (Open): Add String#f method as shortcut for #freezehttps://bugs.ruby-lang.org/issues/90432013-10-22T21:16:59Zheadius (Charles Nutter)headius@headius.com
<p>We have String#b to create a binary-encoded String, and we have the "f" suffix (going away, hopefully) and the "literal".freeze optimization (<a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Use String#freeze and compiler tricks to replace "str"f suffix (Closed)" href="https://bugs.ruby-lang.org/issues/8992">#8992</a>). I think it would be reasonable to add String#f as a shorter method for producing a frozen string.</p>
<p>If String#f is added the "literal".freeze optimization could be dropped in favor of "literal".f. This would provide something very close to the original "literal"f syntax but in a backward-compatibility-friendly way (class String; alias f freeze; end).</p> Ruby master - Feature #9023 (Assigned): Array#tailhttps://bugs.ruby-lang.org/issues/90232013-10-15T13:28:25Zfuadksd (Fuad Saud)fuadksd@gmail.com
<p>I propose the addition of a <code>tail</code> method to the Array class that returns all elements but the first. It is a pretty common pattern in functional programming, but not limited to - I use it extensively in all kinds of apps/gems. The implementation would be pretty trivial, I won't risk a patch to MRI because I'm uninitiated on ruby core matters, but powerpack gem (<a href="http://github.com/bbatsov/powerpack" class="external">http://github.com/bbatsov/powerpack</a>) implements it in ruby in terms of slices.</p> Ruby master - Feature #8850 (Assigned): Convert Rational to decimal stringhttps://bugs.ruby-lang.org/issues/88502013-09-02T10:02:36Znaruse (Yui NARUSE)naruse@airemix.jp
<p>On Ruby 2.1.0, decimal literal is introduced.<br>
It generates Rational but it cannot easily convert to decimal string.<br>
You know, Rational#to_f is related to this but</p>
<ul>
<li>
<p>Float is not exact number<br>
** 0.123456789123456789r.to_f.to_s #=> "0.12345678912345678"</p>
</li>
<li>
<p>it can't handle recursive decimal<br>
** (151/13r).to_f.to_s #=> "11.615384615384615"</p>
</li>
<li>
<p>the method name<br>
** to_decimal<br>
** to_decimal_string<br>
** to_s(format: :decimal)<br>
** extend sprintf</p>
</li>
<li>
<p>how does it express recursive decimal<br>
** (151/13r).to_decimal_string #=> "11.615384..."<br>
** (151/13r).to_decimal_string #=> "11.(615384)"</p>
</li>
</ul>
<p>Example implementation is following.<br>
Its result is<br>
** 0.123456789123456789r.to_f.to_s #=> "0.123456789123456789"<br>
** (151/13r).to_f.to_s #=> "11.(615384)"</p>
<pre><code>class Rational
def to_decimal_string(base=10)
n = numerator
d = denominator
r, n = n.divmod d
str = r.to_s(base)
return str if n == 0
h = {}
str << '.'
n *= base
str.size.upto(Float::INFINITY) do |i|
r, n = n.divmod d
if n == 0
str << r.to_s(base)
break
elsif h.key? n
str[h[n], 0] = '('
str << ')'
break
else
str << r.to_s(base)
h[n] = i
n *= base
end
end
str
end
end
</code></pre> Ruby master - Feature #8839 (Assigned): Class and module should return the class or module that w...https://bugs.ruby-lang.org/issues/88392013-08-31T02:57:19Zheadius (Charles Nutter)headius@headius.com
<p>With the change for <a href="https://bugs.ruby-lang.org/issues/3753" class="external">https://bugs.ruby-lang.org/issues/3753</a>, "def" forms now return the symbolic name of the method defined. Because class and module bodies just return the last expression in their bodies, this means they will now usually end up returning a symbol for the last method defined. This does not seem useful or correct.</p>
<p>I think class and module should return a reference to the class or module just opened. This would make the return value useful and consistent.</p> Ruby master - Feature #8804 (Open): ONCE syntaxhttps://bugs.ruby-lang.org/issues/88042013-08-20T11:45:48Zko1 (Koichi Sasada)
<p>How about to introduce ONCE{...} syntax which do block only once and return the first value?</p>
<ul>
<li>It is similar of BEGIN{} and END{}.</li>
<li>General syntax of /reg/o.</li>
</ul>
<a name="simulation-code"></a>
<h2 >simulation code<a href="#simulation-code" class="wiki-anchor">¶</a></h2>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">ONCE_CACHE</span> <span class="o">=</span> <span class="p">{}</span>
<span class="no">ONCE_MUTEX</span> <span class="o">=</span> <span class="no">Mutex</span><span class="p">.</span><span class="nf">new</span>
<span class="k">def</span> <span class="nf">ONCE</span><span class="p">(</span><span class="o">&</span><span class="n">b</span><span class="p">)</span>
<span class="k">raise</span> <span class="k">unless</span> <span class="nb">block_given?</span>
<span class="no">ONCE_MUTEX</span><span class="p">.</span><span class="nf">synchronize</span><span class="p">{</span>
<span class="n">key</span> <span class="o">=</span> <span class="nb">caller</span><span class="p">(</span><span class="mi">3</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="k">if</span> <span class="n">value</span> <span class="o">=</span> <span class="no">ONCE_CACHE</span><span class="p">[</span><span class="n">key</span><span class="p">]</span>
<span class="n">value</span>
<span class="k">else</span>
<span class="no">ONCE_CACHE</span><span class="p">[</span><span class="n">key</span><span class="p">]</span> <span class="o">=</span> <span class="k">yield</span>
<span class="k">end</span>
<span class="p">}</span>
<span class="k">end</span>
<span class="mi">3</span><span class="p">.</span><span class="nf">times</span><span class="p">{</span><span class="o">|</span><span class="n">i</span><span class="o">|</span>
<span class="nb">p</span> <span class="no">ONCE</span><span class="p">{</span>
<span class="n">i</span> <span class="c1">#=> every time 0</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
<h2></h2>
<a name="Note-that-this-code-doesnt-work-if-two-or-more-ONCE-are-available-in-one-line"></a>
<h2 >Note that this code doesn't work if two or more ONCE{} are available in one line.<a href="#Note-that-this-code-doesnt-work-if-two-or-more-ONCE-are-available-in-one-line" class="wiki-anchor">¶</a></h2> Ruby master - Feature #8678 (Assigned): Allow invalid string to work with regexphttps://bugs.ruby-lang.org/issues/86782013-07-24T14:47:22Znaruse (Yui NARUSE)naruse@airemix.jp
<p>Legacy Ruby 1.8 could regexp match with broken strings.<br>
People can find characters from binary data on the age.</p>
<p>After Ruby 1.9, Ruby raises Exception if it does regexp match with broken strings.<br>
So it became hard to work with character-wise regexp matching with binary data.</p>
<p>Following patch allows it with the constant Regexp::LOOSEENCODING.</p>
<p>commit eb0111ff7ae3f563ce201c4a5f724f121336d42d<br>
Author: NARUSE, Yui <a href="mailto:naruse@ruby-lang.org" class="email">naruse@ruby-lang.org</a><br>
Date: Mon Jul 22 05:37:44 2013 +0900</p>
<pre><code>* Regexp
* New constant:
* Regexp::ENCODINGLOOSE: declare execute matching even if the target string
is invalid byte sequence. [experimental]
</code></pre>
<p>diff --git a/NEWS b/NEWS<br>
index f5fe388..ade0b03 100644<br>
--- a/NEWS<br>
+++ b/NEWS<br>
@@ -35,6 +35,11 @@ with all sufficient information, see the ChangeLog file.</p>
<ul>
<li>misc
<ul>
<li>Mutex#owned? is no longer experimental.</li>
</ul>
</li>
</ul>
<p>+* Regexp</p>
<ul>
<li>
<ul>
<li>New constant:</li>
</ul>
</li>
<li>
<ul>
<li>Regexp::ENCODINGLOOSE: declare execute matching even if the target string</li>
</ul>
</li>
<li>
<pre><code> is invalid byte sequence. [experimental]
</code></pre>
</li>
<li>
</ul>
<ul>
<li>String
<ul>
<li>New methods:
<ul>
<li>String#scrub and String#scrub! verify and fix invalid byte sequence.<br>
diff --git a/re.c b/re.c<br>
index e5cc79d..230a2e0 100644<br>
--- a/re.c<br>
+++ b/re.c<br>
@@ -256,6 +256,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>#define REG_LITERAL FL_USER5<br>
#define REG_ENCODING_NONE FL_USER6<br>
+#define REG_ENCODING_LOOSE FL_USER7</p>
<p>#define KCODE_FIXED FL_USER4</p>
<p>@@ -263,6 +264,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)<br>
(ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)<br>
#define ARG_ENCODING_FIXED 16<br>
#define ARG_ENCODING_NONE 32<br>
+#define ARG_ENCODING_LOOSE 64</p>
<p>static int<br>
char_to_option(int c)<br>
@@ -1251,7 +1253,8 @@ rb_reg_prepare_enc(VALUE re, VALUE str, int warn)<br>
{<br>
rb_encoding *enc = 0;</p>
<ul>
<li>if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {</li>
</ul>
<ul>
<li>if (!(RBASIC(re)->flags & REG_ENCODING_LOOSE) &&</li>
<li>
<pre><code> rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
rb_raise(rb_eArgError,
"invalid byte sequence in %s",
rb_enc_name(rb_enc_get(str)));
</code></pre>
</li>
</ul>
<p>@@ -2433,6 +2436,9 @@ rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,<br>
if (options & ARG_ENCODING_NONE) {<br>
re->basic.flags |= REG_ENCODING_NONE;<br>
}</p>
<ul>
<li>
<p>if (options & ARG_ENCODING_LOOSE) {</p>
</li>
<li>
<pre><code> re->basic.flags |= REG_ENCODING_LOOSE;
</code></pre>
</li>
<li>
<p>}</p>
<p>re->ptr = make_regexp(RSTRING_PTR(unescaped), RSTRING_LEN(unescaped), enc,<br>
options & ARG_REG_OPTION_MASK, err,<br>
@@ -3091,6 +3097,7 @@ rb_reg_options(VALUE re)<br>
options = RREGEXP(re)->ptr->options & ARG_REG_OPTION_MASK;<br>
if (RBASIC(re)->flags & KCODE_FIXED) options |= ARG_ENCODING_FIXED;<br>
if (RBASIC(re)->flags & REG_ENCODING_NONE) options |= ARG_ENCODING_NONE;</p>
</li>
<li>
<p>if (RBASIC(re)->flags & REG_ENCODING_LOOSE) options |= ARG_ENCODING_LOOSE;<br>
return options;<br>
}</p>
</li>
</ul>
<p>@@ -3579,6 +3586,8 @@ Init_Regexp(void)<br>
rb_define_const(rb_cRegexp, "FIXEDENCODING", INT2FIX(ARG_ENCODING_FIXED));<br>
/* see Regexp.options and Regexp.new */<br>
rb_define_const(rb_cRegexp, "NOENCODING", INT2FIX(ARG_ENCODING_NONE));</p>
<ul>
<li>
<p>/* see Regexp.options and Regexp.new */</p>
</li>
<li>
<p>rb_define_const(rb_cRegexp, "LOOSEENCODING", INT2FIX(ARG_ENCODING_LOOSE));</p>
<p>rb_global_variable(&reg_cache);</p>
</li>
</ul>
<p>diff --git a/string.c b/string.c<br>
index 1d784e3..caf0baf 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -3970,7 +3970,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)<br>
cp = sp;<br>
str_enc = STR_ENC_GET(str);<br>
rb_enc_associate(dest, str_enc);</p>
<ul>
<li>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</li>
</ul>
<ul>
<li>
<p>/<em>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</em>/</p>
<p>do {<br>
n++;<br>
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb<br>
index 11e86ec..b8f6897 100644<br>
--- a/test/ruby/test_regexp.rb<br>
+++ b/test/ruby/test_regexp.rb<br>
@@ -8,6 +8,10 @@ class TestRegexp < Test::Unit::TestCase<br>
$VERBOSE = nil<br>
end</p>
</li>
<li>
<p>def u(str)</p>
</li>
<li>
<p>str.dup.force_encoding(Encoding::UTF_8)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<p>def teardown<br>
$VERBOSE = @verbose<br>
end<br>
@@ -958,6 +962,17 @@ class TestRegexp < Test::Unit::TestCase<br>
}<br>
end</p>
</li>
<li>
<p>def test_encoding_loose</p>
</li>
<li>
<p>str = u("\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(".", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Any}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new("\u3042", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Hiragana}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A.\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>str = u("\xf1\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A..\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<a name="This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo"></a>
<h1 >This assertion is for porting x2() tests in testpy.py of Onigmo.<a href="#This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo" class="wiki-anchor">¶</a></h1>
<p>def assert_match_at(re, str, positions, msg = nil)<br>
re = Regexp.new(re) unless re.is_a?(Regexp)</p>
</li>
</ul> Ruby master - Feature #8663 (Open): Officialy alias ArgumentError to ArgErrorhttps://bugs.ruby-lang.org/issues/86632013-07-23T00:07:56ZAnonymous
<p>When not using custom made exceptions, I find myself using TypeError, NameError and ArgumentError the most. ArgumentError is the longest and I would like to suggest to alias it officially as ArgError.</p> Ruby master - Feature #8536 (Assigned): Implement is_numeric? family of methodshttps://bugs.ruby-lang.org/issues/85362013-06-17T12:31:08Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
I think Ruby is in dire need of a convenient method for determining whether a string can be safely converted to a number. It's a trivial problem, but with no trivial solution. The most common methods include using regex, or trying to convert the value to the desired type, rescuring any exceptions that are raised. These are not desirable by any means.</p>
<p>I propose a number of new methods be added, either to each of the number classes such as (({Integer.is_integer?})) and (({Numeric.is_numeric?})), to a single parent such as Numeric. For convenience, corresponding methods may also be added to the String class. The methods I propose are...</p>
<ul>
<li>is_numeric?</li>
<li>is_integer?</li>
<li>is_float?</li>
<li>is_rationale?</li>
</ul>
<p>With the exception of numeric, if each of the other methods return true, that value should be safe to use with the corresponding (({Integer("5")})) style methods, and (({to_i})) methods. These boolean methods should behave like the (({Integer("5")})), in that they should disregard/strip whitespace for example.</p>
<p>I think it'd make a nice feature enhancement to Ruby 2.1.<br>
=end</p> Ruby master - Feature #8478 (Open): The hash returned by Enumerable#group_by should have an empty...https://bugs.ruby-lang.org/issues/84782013-06-03T04:37:46Zphiggins (Pete Higgins)pete@peterhiggins.org
<p>Without this patch, nil checks might need to be done on the return value of Enumerable#group_by:</p>
<p>$ cat test_group_by.rb<br>
a = [1, 2, 3, "a", "b"]<br>
g = a.group_by {|o| o.class }</p>
<p>puts "Fixnums: #{g[Fixnum].size}"<br>
puts "Strings: #{g[String].size}"<br>
puts "Arrays: #{g[Array].size}"</p>
<p>$ ruby test_group_by.rb<br>
Fixnums: 3<br>
Strings: 2<br>
test_group_by.rb:6:in <code><main>': undefined method </code>size' for nil:NilClass (NoMethodError)</p>
<p>This patch adds a default value of an empty array to the hash returned by Enumerable#group_by, so the script above will work:</p>
<p>$ ./ruby -I.:lib test_group_by.rb<br>
Fixnums: 3<br>
Strings: 2<br>
Arrays: 0</p> Ruby master - Feature #8271 (Assigned): Proposal for moving to a more visible, formal process for...https://bugs.ruby-lang.org/issues/82712013-04-16T05:35:58Zheadius (Charles Nutter)headius@headius.com
<p>Proposal for moving to a more visible, formal process for feature requests.</p>
<ol>
<li>Introduction</li>
</ol>
<p>In order to make it clear that an issue or change to MRI is a visible feature change all implementations will need to consider implementing, I propose that we move all feature requests into a separate Redmine project. I see the following benefits to this arrangement:</p>
<ul>
<li>Features are always in one place. One-stop-shopping for implementers to track changes to "Ruby" that are not specific to MRI.</li>
<li>No confusion about where feature requests should be filed. Currently, people usually file feature requests against "trunk", but sometimes against version-specific projects. It's also valid to say that a feature improvement or clarification is not specific to trunk. Tracking features separate from "trunk" and version-specific Redmine projects keeps the process localized to one Redmine project.</li>
<li>Ability to add fields to "feature" issues that do not have relevance for "bugs". For example, bugs do not usually need approval from matz, but features could have an "approved by matz" field. We could also have other metadata tracking other implementations, such as "approved by implementations" or "affects implementations" with drop-downs for known impls. One-stop-shopping to know whether a given impl is affected and/or has agreed to add the feature.</li>
<li>More visible process for folks in the community that can't follow the current process or don't believe there's a process in place.</li>
</ul>
<p>I propose that the project be called CommonRuby (already created and under some use) and be a top-level entry on bugs.ruby-lang.org.</p>
<ol start="2">
<li>Processes</li>
</ol>
<p>For issues that are obviously new features (i.e. user knows to select "feature" in the current tracker), issues would be filed directly in CommonRuby. Discussion proceeds exactly as the current process, perhaps with additional issue fields added that allow tracking matz approval, etc, as stated in §1.</p>
<p>Issues that are approved for a Ruby version will have fields/metadata to indicate at which version the feature is available. This may mean specifying multiple releases if, for example, 2.0.1 and 1.9.3p400 would both see a feature added (just saying 1.9.3p400 is insufficient since the feature does not exist in 2.0.0. This avoids having to track features through the backport process to know if there are multiple releases that contain the feature.</p>
<p>For issues that start out as bugs, but later become features or feature changes, those issues would be tranferred into CommonRuby at the point where it's obvious they're feature-related.</p>
<ol start="3">
<li>Detriments</li>
</ol>
<p>Benefits are stated in the introduction above.</p>
<p>Possible detriments with mitigation:</p>
<ul>
<li>Confusion by users about where to file features.</li>
</ul>
<p>This would be mitigated by adding more information to bug-related home pages about the CommonRuby project. The "feature" value in current "trunk" project could either be removed (after migrating features to CommonRuby) or modified to error/warn or switch the issue to CommonRuby programmatically.</p>
<ul>
<li>More complex process.</li>
</ul>
<p>I believe this process is no more complicated than the current process. It also makes the process of evolving "common Ruby" more isolated from MRI development and may make it easier for users to track that evolution.</p>
<ol start="4">
<li>Further justification</li>
</ol>
<p>A lot of noise has been made over the past several months about Ruby lacking a process for new and changing features. The design process proposed by Brian Shirai (née Ford) gained some measure of popularity, but requires a complete retooling and reworking of current processes, making it infeasible for short-term implementation. Other process-change proposals have been kicked around on ruby-core, but the truth is that there <em>is</em> a current process, even if it's not particularly visible. By implementing my proposal, the process would become more obvious and transparent without major impact to MRI's development or Ruby's evolutionary processes.</p>
<ol start="5">
<li>Prior art</li>
</ol>
<p>The PEP (Python Enhancement Proposal) and JSR (Java Specification Request) processes are partial inspiration for this proposal. The latter governs all visible feature changes to Python independent of bug reports to the main "CPython" implementation. The latter governs (through a heavy and overly-strict process) changes to "Java" independent of individual JVM implementations. Both processes have been very successful at isolating spec changes from implementation changes, although the JSR process tends to move very slowly and be less transparent than it should be.</p>
<ol start="6">
<li>Conclusion</li>
</ol>
<p>Ruby does not lack a process for adding or changing features, but it does lack visibility into that process and in many cases fails to provide tools to non-MRI implementations to participate. Moving feature requests and discussion to a CommonRuby project independent of MRI will make the process more transparent and easier to follow (for users and implementers) while having minimal impact on the current process.</p> Ruby master - Feature #8232 (Open): Rudiments of abstract algebra in Rubyhttps://bugs.ruby-lang.org/issues/82322013-04-07T18:25:12ZAnonymous
<p>I have recently been struggling with Matrix class to make it accept physical magnitudes for matrix multiplication, and at that opportunity (<a href="http://bugs.ruby-lang.org/issues/8223" class="external">http://bugs.ruby-lang.org/issues/8223</a>), I noticed that rings and fields in Ruby do not know their additive identity. Eg. there is no method Float#zero or Rational#zero... I therefore propose that:</p>
<ol>
<li>every ring has #additive_identity, alias #zero method defined.</li>
<li>every ring has other methods defined, as required for rings in abstract algebra. An example (perhaps a stupid example) might be:</li>
</ol>
<p>class << Integer<br>
def additive_identity; 0 end<br>
alias zero additive_identity<br>
def add( other ); self + other end<br>
def additive_inverse; -self end<br>
def multiply( other ); self * other end<br>
def multiplicative_identity; 1 end<br>
end</p>
<ol start="3">
<li>That every field in Ruby has, in addition to the above methods, a method #multiplicative_inverse defined, as in:</li>
</ol>
<p>class << Float<br>
def additive_identity; 0.0 end<br>
alias zero additive_identity<br>
def add( other ); self + other end<br>
def additive_inverse; -self end<br>
def multiply( other ); self * other end<br>
def multiplicative_identity; 1.0 end<br>
alias one multiplicative_identity<br>
def multiplicative_inverse; 1.0 / self end<br>
end</p>
<p>I am no pro mathematician, and abstract algebra first sounded to me like a kind of thing that should be treated in some specialized libraries for math nerds, but looking how Twitter pays people to write abstract algebra in Scala</p>
<p><a href="https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Monoid.scala" class="external">https://github.com/scalaz/scalaz/blob/master/core/src/main/scala/scalaz/Monoid.scala</a></p>
<p>and reading posts like this one about it:</p>
<p><a href="http://stackoverflow.com/questions/14790588/what-is-twitters-interest-in-abstract-algebra" class="external">http://stackoverflow.com/questions/14790588/what-is-twitters-interest-in-abstract-algebra</a></p>
<p>, where especially noteworthy comment is that by Randall Schulz of box.com, fourth from the top.</p>
<p>If we actually require Ruby rings and fields to have the basic properties of rings and fields (just like Enumerable classes are required to have #each method), it would be possible to implement structured objects such as Matrices over them, and instead of intuitively using numeric literals such as 0 and 1, the matrix or another structured object would ask rings / fields, which their elements come from, what their #additive_identity (#zero), #multiplicative_identity (#one) is. And at the same time, I would like to express my wish that Matrix be made a standard part of Ruby, that does not need to be loaded by require.</p> Ruby master - Feature #8229 (Open): extend Hash.include?https://bugs.ruby-lang.org/issues/82292013-04-07T08:14:09Zeike.rb (Eike Dierks)eike@inter.net
<p>I'd like to suggest to extend the Hash.include? method.</p>
<p>Currently Hash.include? can only be used to ask for a key,<br>
I believe it should be extended to ask for a (key value) pair.</p>
<p>I believe this extension can be done without breaking prior api.</p>
<p>I suggest to extend the signature of Hash.include?<br>
to Hash.include?(key, value)</p>
<p>That message should return true,<br>
if the receiving object does have an object at key which is equal to value.</p>
<p>It would be a simple replacement for:<br>
h.include?(key) && h[key] == value</p>
<p>But I do not want to stop there.<br>
I'm heading for h.include_all?(other_hash)<br>
and h.include_any?(other_hash)</p>
<p>and it would be valuable to have h.intersect(other_hash) etc</p>
<p>I believe these to be useful primitives when working with hashes.</p>
<p>I'd like to have the api of the Set class available for the Hash class as well,<br>
but there working on key/value matching.</p>
<p>Obviously any change to such the substantial class as the Hash class<br>
needs a lot of thought for compatibility.</p>
<p>But I believe this can be done without breaking any prior code,<br>
and it could add a lot of new out of the box functionality.</p>
<p>This probably needs some more thought.<br>
We might come up with some dsl like thing like<br>
h.includes.any? or h.includes.all? or h.includes.none?<br>
to be used cross all collection classes.</p>
<p>Someone must be in charge for the Hash class,<br>
my 2p</p> Ruby master - Feature #8164 (Assigned): Public/Privatehttps://bugs.ruby-lang.org/issues/81642013-03-26T07:48:13ZAnonymous
<ul>
<li>#private<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private</a>
<ul>
<li>#private_class_method<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private_class_method" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-private_class_method</a>
</li>
<li>#public<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public</a>
</li>
<li>#public_class_method<a href="http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public_class_method" class="external">http://www.ruby-doc.org/core-1.9.3/Module.html#method-i-public_class_method</a>
</li>
</ul>
</li>
</ul>
<p>Would it be a good idea to compress these 4 methods to 2 methods?</p>
<p>public - Can set both instance <em>and</em> class methods to public by passing<br>
them in as symbol<br>
private - Can set both instance <em>and</em> class methods to private by passing<br>
them in as symbol</p>
<p>and enable them to be called at top of class? Is this a good idea? It would<br>
clean up Module# and encourage use of these two<br>
as methods rather than keywords</p> Ruby master - Feature #8061 (Open): 重複するキーワードをエラーにするhttps://bugs.ruby-lang.org/issues/80612013-03-10T09:53:22Ztadf (tadayoshi funaba)
<p>重複するキーワードをエラーにする。</p>
<p>def m(a:1, b:2)<br>
p [a, b]<br>
end</p>
<p>m(a:8, a:9)</p> Ruby master - Feature #8042 (Assigned): Add Addrinfo#socket to create a socket that is not connec...https://bugs.ruby-lang.org/issues/80422013-03-08T08:35:01Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>This adds a socket method to Addrinfo to get a socket that has not been bound or connected to any address for connectionless operation.</p> Ruby master - Feature #8016 (Assigned): Alias __FILE__ and __LINE__ as methodshttps://bugs.ruby-lang.org/issues/80162013-03-05T12:16:30Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
All of the previous issues discussing the new (({Kernel#<strong>dir</strong>})) method (<a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Kernel#__dir__ (Closed)" href="https://bugs.ruby-lang.org/issues/1961">#1961</a>, <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: __DIR__ revisted (Closed)" href="https://bugs.ruby-lang.org/issues/3346">#3346</a>, <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Why __dir__, not __DIR__ (Rejected)" href="https://bugs.ruby-lang.org/issues/7975">#7975</a>), never came to any conclusion regarding the naming inconsistency between the likes of (({<strong>dir</strong>})) and (({<strong>method</strong>})), and the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})).</p>
<p>Should we not add (({<strong>file</strong>})) and (({<strong>line</strong>})) as methods also, and perhaps deprecate the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})). This would keep it consistant with all the other double-underscore methods. To most developers who perhaps do not know Ruby as intricately as most of the people on this issue tracker, the inconsistency between (({<strong>dir</strong>})) and (({<strong>FILE</strong>})) is not just confusing by name, but the fact that one is a method and one isn't, is doubly confusing. Definitely not principle of least surprise.</p>
<p>This needs to be addressed in my opinion, either through deprecation of (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})), or by keeping those keywords and simply creating Kernel method equivalents for the sake of a consistant API.</p>
<p>While on the topic, someone also suggested in one of those previous issues, to give (({<strong>dir</strong>})) an optional join argument, so you could do something like this:</p>
<pre><code>__dir__('somefile.txt') # => /Users/admin/somefile.txt
</code></pre>
<p>I'd predict that at least 90% of use cases for (({<strong>dir</strong>})) will involve joining it to another path or filename. I can't see any harm in adding this. The naming inconstancies are my main concern however. This would just be a nice bonus that takes advantage of the fact that (({<strong>dir</strong>})) is a method rather than a keyword.<br>
=end</p> Ruby master - Feature #7914 (Open): Case for local class methodshttps://bugs.ruby-lang.org/issues/79142013-02-23T00:13:20Ztrans (Thomas Sawyer)
<p>=begin<br>
Here is a use case for local class methods.</p>
<p>Say we wish to give certain classes and all subclasses a special name.</p>
<p>class X<br>
def self.special_name<br>
"special:#{name}"<br>
end<br>
end<br>
class Y < X; end<br>
class Z < Y; end</p>
<p>Z.special_name #=> "special:Z"</p>
<p>But what if Y has a unique special name?</p>
<p>class Y < X<br>
def special_name<br>
'unique:Y'<br>
end<br>
end</p>
<p>Problem that arises:</p>
<pre><code>Z.special_name #=> "unique:Y" # wrong!
</code></pre>
<p>Currently, to solve this would require creating an additional method, e.g. <code>unique_name</code> and redefine <code>special_name</code> to first look for unique_name then fallback to default special name if non-found. It works, but adds additional complexity to API.</p>
<p>Nicer solution would be local class methods.</p>
<pre><code>class Y < X
def special_name
'unique:Y'
end
local :special_name
end
Y.special_name #=> "unique:Y"
Z.special_name #=> "special:Z"
</code></pre>
<p>The idea being that local class methods are skipped in super/lookup chain.</p>
<p>This idea is not without precedence. Module class methods can be thought of as being local. So this idea has other side of the notion, that modules could have class methods that are not skipped over in the super/lookup chain. In that case we would need a term that means opposite of local, so I'll use <code>nonlocal</code>:</p>
<pre><code>module M
def self.q; "q"; end
nonlocal :q
end
class X
include M
end
X.q #=> "q"
</code></pre>
<p>=end</p> Ruby master - Feature #7883 (Open): Add Regex#to_prochttps://bugs.ruby-lang.org/issues/78832013-02-19T16:58:30Zrklemme (Robert Klemme)shortcutter@googlemail.com
<p>Just a small addition to the standard library:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Regexp</span>
<span class="k">def</span> <span class="nf">to_proc</span><span class="p">;</span> <span class="nb">lambda</span> <span class="p">{</span><span class="o">|</span><span class="n">s</span><span class="o">|</span> <span class="nb">self</span> <span class="o">=~</span> <span class="n">s</span><span class="p">}</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>With that one can use a <code>Regexp</code> everywhere a <code>Proc</code> is used as filtering criteria saving a bit of typing. While we have <code>Enumerable#grep</code> already there may be other cases where you want to do something like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">00</span><span class="mi">8</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="sx">%w{foo bar baz}</span><span class="p">.</span><span class="nf">select</span> <span class="o">&</span><span class="sr">/\Ab/</span>
<span class="o">=></span> <span class="p">[</span><span class="s2">"bar"</span><span class="p">,</span> <span class="s2">"baz"</span><span class="p">]</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">00</span><span class="mi">9</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="sx">%w{foo bar baz}</span><span class="p">.</span><span class="nf">reject</span> <span class="o">&</span><span class="sr">/\Ab/</span>
<span class="o">=></span> <span class="p">[</span><span class="s2">"foo"</span><span class="p">]</span>
<span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">010</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="sx">%w{foo bar baz}</span><span class="p">.</span><span class="nf">find</span> <span class="o">&</span><span class="sr">/\Ab/</span>
<span class="o">=></span> <span class="s2">"bar"</span>
</code></pre>
<p>Note: line 9 and 10 are not possible with <code>Enumerable#grep</code> AFAIK.</p>
<p>I see low risk of breaking something.</p> Ruby master - Feature #7876 (Open): Add method for accessing Class from within Singleton Classhttps://bugs.ruby-lang.org/issues/78762013-02-18T19:59:29Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
I'm quite surprised I haven't run into this sooner, but I seem to have just discovered that there's no means by which you can access the outer Class object once inside the context of the Singleton Class. Take the following example; how would I get a reference to (({Test})) from within the singleton?</p>
<p>class Test<br>
class << self<br>
# How do I get a reference to Test from here?<br>
end<br>
end</p>
<p>I assume the answer is that there is no reliable way, hence the reason for this request. Could we add a method to the singleton class that allows access to the "outer" class, e.g.</p>
<p>class Test<br>
class << self<br>
self.outerclass<br>
end<br>
end</p>
<p>Thoughts?<br>
=end</p> Ruby master - Feature #7848 (Open): Restore default state for core ruby objectshttps://bugs.ruby-lang.org/issues/78482013-02-14T04:41:33Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Hi.</p>
<p>Consider:</p>
<p>class String<br>
def lala<br>
puts 'Running lala() from class String.'<br>
end<br>
end</p>
<p>This is possible.</p>
<p>My question is - is there a reason why we can not restore<br>
to the default ruby state again?</p>
<p>For instance, if I would do:</p>
<p>String.restore</p>
<p>I could undo all modifications to String, save what was used<br>
in String class on startup/initialize.</p>
<p>The reason I would like to have something like this is so<br>
that I could safely undo all "monkey" patches again, if needed,<br>
for a given project.</p> Ruby master - Feature #7795 (Open): Symbol.defined? and/or to_existing_symbolhttps://bugs.ruby-lang.org/issues/77952013-02-07T14:08:11ZStudent (Nathan Zook)blogger@pierian-spring.net
<p>I'm pulling this out from deep in the discussions of issue <a href="http://bugs.ruby-lang.org/issues/7791" class="external">http://bugs.ruby-lang.org/issues/7791</a>, Let Symbols be Garbage Collected.</p>
<p>The problem is that the extreme utility of symbols makes them enticed to use, which results in a DOS vulnerability. My proposal is to add either of a pair of methods that would make it easy to defend against a DOS along these lines.</p>
<p>#1) Symbol.defined?</p>
<p>In existing code, it would might like this:<br>
class Symbol<br>
def self.defined?(string)<br>
all_symbols.any?{|sym| sym.to_s == string}<br>
end<br>
end</p>
<p>#2) to_existing_sym. This would be defined in the same places as to_sym, but would through an argument error if the symbol did not already exist.</p> Ruby master - Feature #7748 (Open): Contextual sendhttps://bugs.ruby-lang.org/issues/77482013-01-28T16:11:40Ztrans (Thomas Sawyer)
<p>=begin<br>
If I write a method that uses #send vs. #public_send, I am making an assumption about how that method is invoked. For example, take the simplest form of such a method:</p>
<p>class String<br>
def send_out(op, *a, &b)<br>
send(op, *a, &b)<br>
end<br>
end</p>
<p>This code has a bug in it, in the sense that it can be used to call private string methods. The solution is to use #public_send. In most cases that will be fine. But if anyone tries to reuse the method while extending String themselves, e.g.</p>
<p>class String<br>
def send_out(op, *a, &b)<br>
public_send(op, *a, &b)<br>
end</p>
<pre><code>def some_public_method
send_out(:some_private_method)
end
private
def some_private_method
end
</code></pre>
<p>end</p>
<p>Then it will be a problem b/c it cannot be used on a private supporting method.</p>
<p>So it seems like there should be something like a ((<em>contextual send</em>)) which invokes a send with the same visibility as the parent method is invoked. e.g.</p>
<p>class String<br>
def send_out(op, *a, &b)<br>
contextual_send(op, *a, &b)<br>
end<br>
end</p>
<p>And then all cases will work as expected.<br>
=end</p> Ruby master - Feature #7739 (Assigned): Define Hash#| as Hash#reverse_merge in Railshttps://bugs.ruby-lang.org/issues/77392013-01-24T21:57:20Zalexeymuranov (Alexey Muranov)
<p>=begin<br>
I suggest for to define (({Hash#|})) as (({Hash#reverse_merge})) in ((<em>Rails</em>)), in my opinion this would correspond nicely to (({Set#|})), to the logical (({#||})) and to the bitwise (({#|})):</p>
<p>{ :a => 1, :b => 2 } | { :b => 1, :c => 2 } # => { :a => 1, :b => 1, :c => 2 }<br>
=end</p> Ruby master - Feature #7704 (Open): Add a list of enabled (experimental) language features.https://bugs.ruby-lang.org/issues/77042013-01-16T10:54:37Zmpapis (Michal Papis)mpapis@gmail.com
<p>With multiple Ruby implementations and "experimental" features like "refinements" it would be nice to have an array or hash including list of enabled language features so developers could check it instead of auto-discovering code with some hacks.</p>
<p>Additionally a new keyword like <code>require_features :refinements, ...</code> could be introduced to allow easy validation via either exception or return status.</p> Ruby master - Feature #7702 (Open): Remove Proc#bindinghttps://bugs.ruby-lang.org/issues/77022013-01-16T09:09:14Zjballanc (Joshua Ballanco)jballanc@gmail.com
<p>=begin<br>
As discussed in the most recent Ruby implementer's meeting and elsewhere over the years, being able to get a handle to the binding of any block/proc has a number of problems:</p>
<ul>
<li>Code execution after passing a block/proc in unpredictable, as the binding of said proc can be used to redefine any local, instance variable, method, class, module, etc.</li>
<li>Potentially sensitive data can leak out of the scope of a method via a proc binding</li>
<li>Large object graphs may need to be retained for the lifetime of a proc, since any identifier in scope at the time of proc creation must remain live in the event that the binding of the proc is used to evaluate code</li>
</ul>
<p>Additionally, removal of Proc#binding would enable a number of very useful optimizations and performance improvements.<br>
=end</p> Ruby master - Feature #7657 (Open): Array#& doesn't accept Enumerableshttps://bugs.ruby-lang.org/issues/76572013-01-06T09:00:39ZNevir (Ian MacLeod)ian@nevir.net
<p>This seems similar to <a href="http://bugs.ruby-lang.org/issues/6923" class="external">http://bugs.ruby-lang.org/issues/6923</a></p>
<p>Example:</p>
<pre><code>irb(main):001:0> class Thing
irb(main):002:1> include Enumerable
irb(main):003:1> def each(*args, &block)
irb(main):004:2> [1,2,3,4,5].each(*args, &block)
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):007:0> Array(Thing.new) & [1,3,5]
=> [1, 3, 5]
irb(main):008:0> [1,3,5] & Thing.new
TypeError: can't convert Thing into Array
irb(main):009:0> Thing.class_eval do
irb(main):010:1* alias_method :to_ary, :to_a
irb(main):011:1> end
=> Thing
irb(main):012:0> [1,3,5] & Thing.new
=> [1, 3, 5]
</code></pre>
<p>Would it make sense for Enumerable to implement to_ary as well? Or is this purely a bug in Array#&?</p> Ruby master - Feature #7654 (Open): Add optional code block to IO::readlineshttps://bugs.ruby-lang.org/issues/76542013-01-04T22:15:05Zshock_one (Володимир Шацький)shockone89@gmail.com
<p>Of course, we always can write something like<br>
File.readlines('/home/shock_one/test.rb').map{ |line| line.upcase }<br>
but this way we create unneeded intermediate array which can be pretty big.<br>
There is also a method IO::foreach, but it doesn't collect return values.<br>
Besides it seems pretty logical and natural to have a block in this method.</p> Ruby master - Feature #7644 (Assigned): In refinements, change "using" keyword to a less generic ...https://bugs.ruby-lang.org/issues/76442013-01-01T23:03:33ZAnonymous
<p>The upcoming feature of refinements is bringing two new keyords: "refine Something" and "using Something". While I am definitely late to come up with this, I realized that due to natural linguistic reasons, keyword "using" should be replaced another word. This suggestion is not about functionality, only about the keyword choice. I firmly believe that "using", while tempting and beautiful, is ultimately wrong keyword choice, imposing undue strain on English speaking about code in comments, documentation, and all developer communication.</p>
<p>Rationale: Ruby keywords, especially verbs (include, extend, raise, return, yield, ...) and nouns (class, module, ...) constrain speaking about code. One eg. cannot freely speak about modules in the general sense ("My program has modular structure consisting of three main modules blah blah..."), due to the danger of confusion that we are speaking about three Module instances. This has to be circumvented by saying eg. "My program consists of three main orthogonal parts blah blah..."). Now if Ruby 2.1 would introduce keyword "part", we would have to reformulate the sentence to eg. "My program consists of three main independent subprograms..." What am I getting at is, that PLEEEASE don't take "use", "using", "usage" etc. away from meeee! I don't want write poetry in the documentation!</p>
<p>Suggested solution: One simple solution would be to replace the participle "using Something" by a keyword selected from eg. prepositions or adverbs, such as "with Something". If verb or noun is desired, it should not constrain natural speech too much, such as "gimmick Something", or "delve Something".</p> Ruby master - Feature #7614 (Open): alias_accessorhttps://bugs.ruby-lang.org/issues/76142012-12-24T11:19:06Ztrans (Thomas Sawyer)
<p>=begin<br>
Prior issue reminded me that I've been meaning to ask for this for a while, as I use is fairly often.</p>
<p>In pure Ruby the definition is essentially:</p>
<pre><code>def alias_accessor(name, origin)
alias_method "#{name}=", "#{origin}="
alias_method name, origin
end
</code></pre>
<p>Albeit pursuit to prior mentioned issue, I'd define it more like:</p>
<pre><code>def alias_accessor(name, origin)
writer_name = name.to_s.chomp('?')
alias_method "#{writer_name}=", "#{origin}="
alias_method name, origin
end
</code></pre>
<p>=end</p> Ruby master - Feature #7611 (Open): Focal method for all loads/requireshttps://bugs.ruby-lang.org/issues/76112012-12-23T23:50:40Ztrans (Thomas Sawyer)
<p>=begin<br>
Presently Ruby has seven methods for importing code. These are:</p>
<ul>
<li>(({Kernel#load}))</li>
<li>(({Kernel#require}))</li>
<li>(({Kernel#relative_require}))</li>
<li>(({Kernel.load}))</li>
<li>(({Kernel.require}))</li>
<li>(({Kernel.relative_require}))</li>
<li>(({Kernel#autoload}))</li>
</ul>
<p>Even though the Kernel module methods do the same thing as the instance methods, all of these act independently. If you need to tap into or override code loading in general it means doing so for each and every one.</p>
<p>Would it not be much more elegant if they all called upon one focal method? Lacking another name for this example, lets call it (({#open_eval()})). The method would take a path argument and options for (({feature})), (({relative})) and (({wrap})), where if (({feature})) is true then it is a "require", otherwise it is a "load".</p>
<p>def open_eval(path, feature: false, relative: false, wrap: nil)<br>
...<br>
end</p>
<p>All the other seven methods listed above would route to this one method. So it would then be possible to monitor or override this behavior, e.g. like RubyGems does, via a single interface.</p>
<p>Note, even if this feature request is not accepted, I would like to get some opinion on it, b/c I am currently working on a project where I have to do this (specifically I am in need of require/load callbacks). For the purpose I have created another reusable gem for it and I want to get an idea of what would be considered appropriate API for it.<br>
=end</p> Ruby master - Feature #7604 (Open): Make === comparison operator ability to delegate comparison t...https://bugs.ruby-lang.org/issues/76042012-12-22T21:04:06Zprijutme4ty (Ilya Vorontsov)prijutme4ty@gmail.com
<p>=begin<br>
I propose to expand default behaviour of === operator in the following way:<br>
Objects have additional instance method Object#reverse_comparison?(other) which is false by default in all basic classes.<br>
Each class that overrides Object#===(other) should check whether reverse_comparison? is true or false<br>
If it is false, behavior is not changed at all.<br>
If it is true, comparison is delegated to === method of an argument with self as an argument.</p>
<p>This technique can help in constructing RSpec-style matchers for case statement. Example:</p>
<a name="usual-method-call"></a>
<h1 >usual method call<a href="#usual-method-call" class="wiki-anchor">¶</a></h1>
<p>arr = %w[cat dog rat bat]<br>
puts arr.end_with?(%w[dog bat]) # ==> false<br>
puts arr.end_with?(%w[rat bat]) # ==> true<br>
puts arr.end_with?(%w[bat]) # ==> true</p>
<a name="predicate-style-case"></a>
<h1 >predicate-style case<a href="#predicate-style-case" class="wiki-anchor">¶</a></h1>
<p>case %w[cat dog rat bat].end_with?<br>
when %w[dog bat]<br>
puts '..., dog, bat'<br>
when %w[rat bat]<br>
puts '..., rat, bat'<br>
when %w[bat]<br>
puts '..., bat'<br>
else<br>
puts 'smth else'<br>
end</p>
<a name="gt-rat-bat"></a>
<h1 >==> ..., rat, bat<a href="#gt-rat-bat" class="wiki-anchor">¶</a></h1>
<p>Code needed to run this is not very complex:<br>
class Object<br>
def reverse_comparison?(other)<br>
false<br>
end<br>
alias_method :'old===', :'==='<br>
def ===(other)<br>
(other.reverse_comparison?(self) ? (other.send 'old===',self) : (self.send 'old===',other))<br>
end<br>
end</p>
<p>class Predicate<br>
def initialize(&block)<br>
@block = block<br>
end<br>
def reverse_comparison?(other)<br>
true<br>
end<br>
def ===(*args)<br>
@block.call(*args)<br>
end<br>
end</p>
<p>class Array<br>
alias_method :'old===', :'==='<br>
def ===(other)<br>
other.reverse_comparison?(self) ? (other.send('===',self)) : (self.send('old===',other))<br>
end</p>
<pre><code>def end_with?(expected_elements = nil)
return last(expected_elements.size) == expected_elements if expected_elements
Predicate.new{|suffix| last(suffix.size) == suffix }
end
</code></pre>
<p>end</p>
<p>This technique looks powerful and beautiful for me. One detail is that obj#reverse_comparison? can distinguish different types of arguments and returns true only for certain types of given object. Also this can be used to prevent double-mirroring (as shown below)</p>
<p>The problem is that many base classes already defined custom === operator, so each of those classes (Fixnum, Float, String, Regexp, Range etc) should be redefined in such a way to make a solution full-fledged.<br>
Another problem is case that both objects defined reverse_comparison? to return true. In my solution Predicate#=== just ignores result of revese_comparison? which is not consistent.<br>
Another possible way is to raise errors on double mirroring:<br>
def reverse_comparison?(other)<br>
raise 'double mirroring' if @__mirroring_started<br>
@__mirroring_started = true<br>
return true unless other.reverse_comparison?(self)<br>
false<br>
ensure<br>
remove_instance_variable :@__mirroring_started<br>
end</p>
<p>My proposal is to add reverse_comparison? method and change base classes operator === to use its result as shown above. May be it's worth also to make a class analogous to Predicate in stdlib.<br>
=end</p> Ruby master - Feature #7580 (Assigned): Range translationhttps://bugs.ruby-lang.org/issues/75802012-12-17T14:43:24ZAnonymous
<p>=begin<br>
I would like to propose the (({#+})) and (({#-})) methods on (({Range})).</p>
<p>These would be useful for translating ranges - for example, given a range where the endpoints are 1-indexed, the range could be translated by 1 in the negative direction to use in (({Array#[]})).</p>
<p>Instead of doing a syntactically-bulky manual translation like so:</p>
<p>ary[(range.begin - 1)..(range.end - 1)]</p>
<p>(({Range#-})) could be used instead:</p>
<p>ary[range - 1]</p>
<p>The translation methods would not handle certain endpoint types specially, they would just pass the call on.</p>
<p>Here's an example implementation in Ruby:</p>
<p>class Range<br>
def +(other)<br>
Range.new(self.begin + other, self.end + other, exclude_end?)<br>
end</p>
<pre><code>def -(other)
Range.new(self.begin - other, self.end - other, exclude_end?)
end
</code></pre>
<p>end</p>
<p>=end</p> Ruby master - Feature #7548 (Open): Load and Require Callbackshttps://bugs.ruby-lang.org/issues/75482012-12-12T13:15:48Ztrans (Thomas Sawyer)
<p>=begin<br>
Should #load and #require have callbacks? e.g.</p>
<p>def required(path)<br>
...<br>
end</p>
<p>def loaded(path, wrap)<br>
...<br>
end</p>
<p>On occasion I have wanted to do load monitoring to track down a bug. This would have made it easier.</p>
<p>Are there any other good use cases?<br>
=end</p> Ruby master - Feature #7546 (Open): Change behavior of `Array#slice` for an argument of `Range` c...https://bugs.ruby-lang.org/issues/75462012-12-12T01:23:22Zalexeymuranov (Alexey Muranov)
<p>=begin<br>
This is a concrete proposal to "fix" <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Inconsistent Array.slice() (Rejected)" href="https://bugs.ruby-lang.org/issues/4541">#4541</a>.</p>
<p>It is also related to <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Make Range act as a "lazy ordered set" (Open)" href="https://bugs.ruby-lang.org/issues/7545">#7545</a>.<br>
For this proposal to make good sense, i think it would be nice if <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Make Range act as a "lazy ordered set" (Open)" href="https://bugs.ruby-lang.org/issues/7545">#7545</a> was at least partially accepted.</p>
<p>=== Main proposal</p>
<p>I propose (({Array#slice})) with (({Range})) type argument to work as follows:</p>
<p>a = ['0', '1', '2', '3']<br>
a[1..2] # => ['1', '2']<br>
a[-2..-1] # => ['2', '3']<br>
a[2..1] # => ['2', '1']<br>
a[-1..-2] # => ['3', '2']<br>
a[-1..1] # => ['3', '0', '1']<br>
a[1..-1] # => ['1', '0', '3']<br>
a[1..1] # => ['1']<br>
a[1...1] # => []<br>
a[4..4] # => [nil]<br>
a[4...4] # => []<br>
a[9..9] # => [nil]<br>
a[9...9] # => []<br>
a[1..5] # => ['1', '2', '3', nil, nil]</p>
<p>=== Secondary proposal: consider adding new instance methods to (({Array})) to compensate the changed behavior of (({Array#slice}))</p>
<p>If this proposal is accepted, the code "(({a[1..-2]}))" for an array (({a})) will not work as before.<br>
This can be compensated by adding new instance methods to (({Array})).<br>
For example the following ones.</p>
<ol>
<li>(({Array#clip(fixnum, fixnum)})):</li>
</ol>
<p>['0', '1', '2', '3'].clip(1, 1) # => ['1', '2']</p>
<p>Thus (({a.clip(1, 1)})) would be a replacement for (({a[1..-2]})).</p>
<p>(It looks strange to have to convert a pair of numbers ((<em>m</em>)) and ((<em>n</em>)) into a range (({m..(-1-n)})) to simply ask an array to remove ((<em>m</em>)) elements from the beginning and ((<em>n</em>)) elements from the end.<br>
If <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Make Range act as a "lazy ordered set" (Open)" href="https://bugs.ruby-lang.org/issues/7545">#7545</a> is accepted, then the "(({a[1..-2]}))" syntax for "clipping" an array will make not much sense and maybe will not be possible.)</p>
<ol start="2">
<li>(({Array#from(fixnum)})), (({Array#till(fixnum)})):</li>
</ol>
<p>a = ['0', '1', '2', '3']<br>
a.from(1) # => ['1', '2', '3']<br>
a.till(1) # => ['0', '1']<br>
a.from(1).till(-2) # => ['1', '2']</p>
<p>In fact, in ((<em>Rails</em>)) (({ActiveSupport})) there are methods (({Array#from})) and (({Array#to})) like this, but unfortunately they do not accept negative indices.</p>
<p>((<em>Remark</em>)). It would also be possible to have (({Array#clip!})), (({Array#from!})), (({Array#till!})).<br>
=end</p> Ruby master - Feature #7503 (Assigned): make timeout.rb async-interrupt safe by defaulthttps://bugs.ruby-lang.org/issues/75032012-12-03T22:33:41Zkosaki (Motohiro KOSAKI)kosaki.motohiro@gmail.com
<p>Hi</p>
<p>Again and again we discussed, current timeout.rb is very dangerous because ExitException interrupt argument code and unwind call stack immediately.<br>
It may prevent to run ensure block and makes resource leak.</p>
<p>I proposed change default to interrupted only on blocking point.</p>
<p>patch is here.<br>
<a href="https://gist.github.com/4195015" class="external">https://gist.github.com/4195015</a></p>
<p>I also propse to add 'immediate' optional argument because it may help to make a workaround timeout.rb + zero blocking point corner case.</p>
<p>What do you think?</p> Ruby master - Feature #7444 (Open): Array#product_sethttps://bugs.ruby-lang.org/issues/74442012-11-27T14:44:28Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I'd like to propose <code>Array#product_set</code> to return the product set of arrays (aka cartesian product)</p>
<pre><code>deck = [1..13, %i(spades hearts diamond clubs)].product_set
# => <#Enumerator ...>
deck.first(2) # => [[1, :spades], [2, :spades]]
</code></pre>
<p><code>product_set</code> would return an enumerator if no block is given. It should raise an error if an element of the array is not an Enumerable, like Array#transpose or #zip do.</p>
<p>Although <code>Array.product</code> would be acceptable too, I feel that an instance method of array is best in the case, in the same way that <code>transpose</code> is an instance method and not a class method.</p>
<p>The name "product_set" is a correct mathematical term. Although the synonym "cartesian_product" would also be acceptable, I propose "product_set" because it is shorter and cute too. I feel it is even clearer than <code>product</code>; the first time I head of <code>product</code> I was convinced that <code>[2,3,7].product # => 42</code>.</p>
<p>Addressing objections raised in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Array::zip (Rejected)" href="https://bugs.ruby-lang.org/issues/6499">#6499</a>:</p>
<ol>
<li>This is not for the sake of symmetry, but because often we have an array of the arrays we want a product of.</li>
</ol>
<p>It is cumbersome to write <code>arrays.first.product(*arrays[1..-1])</code> or similar and it hides what is going on.</p>
<p>Writing <code>arrays.product_set</code> is much nicer.</p>
<ol start="2">
<li>
<p>The goal is not mainly to get a lazy version, but more to make the API better. The fact that it returns an Enumerator if no block is given is just a bonus :-)</p>
</li>
<li>
<p>[].product_set.to_a # => [[]]</p>
</li>
</ol>
<p>This can be seen from a cardinality argument, or for example because <code>array.repeated_permutation(n) == Array.new(n, array).product_set.to_a</code> and <code>array.repeated_permutation(0) == [[]]</code>.</p> Ruby master - Feature #7436 (Assigned): Allow for a "granularity" flag for backtrace_locationshttps://bugs.ruby-lang.org/issues/74362012-11-26T07:06:40Zsam.saffron (Sam Saffron)sam.saffron@gmail.com
<p>related to <a href="http://bugs.ruby-lang.org/issues/7051" class="external">http://bugs.ruby-lang.org/issues/7051</a></p>
<p>Sometimes one need less information (or more information) associated with backtraces.</p>
<p>It would be nice if one could send in a separate flag informing the VM about the granularity of information required, eg:</p>
<p>caller_locations(0,-current_depth, BacktraceInfo::Label & BacktraceInfo::Lineno)</p>
<p>This allows for one to take quicker backtraces if they need less information, additionally BacktraceInfo::Bindings and BacktraceInfo::Klass could be added which allow you to gather more information for heavy profiling / diagnostics.</p> Ruby master - Feature #7377 (Open): #indetical? as an alias for #equal?https://bugs.ruby-lang.org/issues/73772012-11-17T09:47:45Zaef (Alexander E. Fischer)aef@raxys.net
<p>As my feature request <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: #eql? and #equal? naming (Rejected)" href="https://bugs.ruby-lang.org/issues/7359">#7359</a> got rejected, here a more backward-compatible approach:</p>
<p>In my opinion the difference between #eql? and #equal? is really unintuitive. How about making their difference more obvious by giving one of them a more accurate name?</p>
<p>My proposal is to alias #equal? to #identical?.</p>
<p>I'll write a patch, if this is acceptable.</p>