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 #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 #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 #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 #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 #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 - 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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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 #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> Ruby master - Feature #7349 (Assigned): Struct#inspect needs more meaningful outputhttps://bugs.ruby-lang.org/issues/73492012-11-14T11:32:05Zpostmodern (Hal Brodigan)postmodern.mod3@gmail.com
<p>When inheriting directly from Struct.new, Class#ancestors shows a meaningless anonymous Class:</p>
<pre><code>class Point < Struct.new(:x, :y)
def distance
((x ** 2) + (y ** 2)) ** 0.5
end
end
Point.ancestors
# => [Point, #<Class:0x007fe204a1a228>, Struct, Enumerable, Object, Kernel, BasicObject]
</code></pre>
<p>Perhaps, the anonymous Class could list the Struct's fields?</p>
<pre><code>#<Class:x, y>
</code></pre> Ruby master - Feature #7121 (Assigned): Extending the use of `require'https://bugs.ruby-lang.org/issues/71212012-10-09T10:09:29Zmjones (Morgan Jones)integ3rs@gmail.com
<p>=begin<br>
I was playing with Ruby tonight and thought up an interesting idea to make (({require})) a bit better, so you can load multiple files sequentially using one method call.</p>
<p>Currently, (({require})) supports one argument, and throws a (({TypeError})) if you pass an array:</p>
<p>irb(main):001:0> require %w(json yaml)<br>
TypeError: can't convert Array into String</p>
<p>However, there's a way to patch Kernel that makes it respond to multiple objects passed in an (({Array})).</p>
<p>module Kernel<br>
@@require = method :require</p>
<p>def require *args<br>
args.flatten!<br>
args.collect! do |a|<br>
raise ArgumentError.new "arguments to `require' must be strings or symbols" unless a.is_a?(String) || a.is_a?(Symbol)<br>
@@require.call a.to_s<br>
end</p>
<pre><code> args.length == 1 ? args.first : args
</code></pre>
<p>end<br>
end</p>
<p>The new behavior doesn't actually require the modification of any code that calls (({require})) (pretty much anything, really), and new code can take advantage of the new functionality instantly.</p>
<p>irb> require %w(json yaml)<br>
=> [true, false]<br>
irb> require :pp<br>
=> false<br>
irb> require 'rails'<br>
=> true<br>
irb> require %w(json yaml), :pp, 'rails'<br>
=> [true, false, false, true]<br>
=end</p>
<p>Thanks for considering this.</p> Ruby master - Feature #6869 (Open): Do not treat `_` parameter exceptionallyhttps://bugs.ruby-lang.org/issues/68692012-08-15T06:50:54Zalexeymuranov (Alexey Muranov)
<p>I started by commenting on <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Don't warn for unused variables starting with _ (Closed)" href="https://bugs.ruby-lang.org/issues/6693">#6693</a>, but i have realized that this is a slightly different request.</p>
<p>I propose to not treat the variable name "<code>_</code>" exceptionally. Current behavior:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="p">{</span><span class="mi">0</span><span class="o">=></span><span class="mi">1</span><span class="p">}.</span><span class="nf">each_with_index</span> <span class="p">{</span> <span class="o">|</span><span class="n">_</span><span class="p">,</span><span class="n">_</span><span class="o">|</span> <span class="nb">p</span> <span class="n">_</span> <span class="p">}</span> <span class="c1"># [0, 1]</span>
</code></pre>
<p>prints "[0, 1]", but</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="p">{</span><span class="mi">1</span><span class="o">=></span><span class="mi">2</span><span class="p">}.</span><span class="nf">each_with_index</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="p">,</span><span class="n">x</span><span class="o">|</span> <span class="nb">p</span> <span class="n">x</span> <span class="p">}</span> <span class="c1"># SyntaxError: (eval):2: duplicated argument name</span>
</code></pre>
<p>raises "SyntaxError: (eval):2: duplicated argument name".</p>
<p>Similarly for methods:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">_</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span>
<span class="n">_</span>
<span class="k">end</span>
<span class="n">f</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span> <span class="c1"># => 0</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">x</span><span class="p">)</span>
<span class="n">x</span>
<span class="k">end</span> <span class="c1"># => SyntaxError: (eval):2: duplicated argument name</span>
</code></pre>
<p>Observe also that the use of repeated <code>_</code> parameter is not consistent between methods and blocks: for methods the value is the first assigned value, and for blocks it is the array of all the assigned values.</p>
<ol>
<li>I propose to use the same rule for all variables, without distinguishing <code>_</code> specially.</li>
</ol>
<p>In particular i propose to allow to repeat any variable, not only <code>_</code>, in block or method arguments without raising an error.</p>
<p>There may be several solutions what the repeated argument will hold: it may hold the array of all assigned values, the first assigned value, the last assigned value, the first non-nil assigned value, or the last non-nil assigned value.</p>
<ol start="2">
<li>
<p>I propose to treat repeated arguments in methods and in blocks the same way (do not know which one).</p>
</li>
<li>
<p>For unused variables i propose to introduce a special placeholder, for example "<code>-</code>" not followed by anything other than a delimiter (comma or bracket):</p>
</li>
</ol>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">each_with_index</span> <span class="p">{</span> <span class="o">|-</span><span class="p">,</span> <span class="n">value</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">value</span> <span class="p">}</span>
<span class="o">-</span><span class="p">,</span> <span class="o">-</span><span class="p">,</span> <span class="n">suffix</span> <span class="o">=</span> <span class="n">parse</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
</code></pre> Ruby master - Feature #6841 (Assigned): Shorthand for Assigning Return Value of Method to Selfhttps://bugs.ruby-lang.org/issues/68412012-08-07T11:37:53Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
Quite often in Ruby, I find myself doing something like: (({my_var[:foo][:bar] = my_var[:foo][:bar].to_i})) or (({obj.foo.bar = obj.foo.bar.to_i})). Realising this, I thought of what would be a fairly nice shorthand syntax for this, which could be: (({my_var[:foo][:bar] .= to_i})). How this works should be pretty self-explanatory. The (({.=})) operator works exactly like any other assignment operator of this nature.</p>
<p>Would be nice to see this in Ruby 2.0. Wondering what others think of this?<br>
=end</p> Ruby master - Feature #6817 (Open): Partial applicationhttps://bugs.ruby-lang.org/issues/68172012-07-31T15:38:35Zcitizen428 (Michael Kohl)citizen428@gmail.com
<p>I know that what I propose here is a significant change to Ruby, but it's part of my ongoing quest to get some more functional programming features into Ruby (see also <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: Array#zip_with (Assigned)" href="https://bugs.ruby-lang.org/issues/4539">#4539</a> and <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: public #self (Closed)" href="https://bugs.ruby-lang.org/issues/6373">#6373</a>).</p>
<p>I was wondering if it would make sense to maybe introduce partial application to Ruby? So that instead of</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">3</span><span class="p">).</span><span class="nf">map</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">2</span> <span class="p">}</span>
</code></pre>
<p>or the somewhat unwieldy</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">3</span><span class="p">).</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="mi">2</span><span class="p">.</span><span class="nf">method</span><span class="p">(:</span><span class="o">+</span><span class="p">))</span>
</code></pre>
<p>one could just write</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">3</span><span class="p">).</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="mi">2</span><span class="p">.</span><span class="nf">+</span><span class="p">)</span>
</code></pre>
<p>which I think has a quite rubyish feel to it. I have a POC implementation in Ruby (I tried it with various <code>Fixnum</code> methods) over at <a href="http://citizen428.net/blog/2012/07/30/ruby-left-section-for-infix-operators" class="external">my blog</a>, but that was just a quick hack and obviously I don't want to monkey-patch every method with arity 1, but it was a nice way of exploring possible syntax.</p> Ruby master - Feature #6811 (Assigned): File, Dir and FileUtils should have bang-versions of sing...https://bugs.ruby-lang.org/issues/68112012-07-29T20:34:08Zprijutme4ty (Ilya Vorontsov)prijutme4ty@gmail.com
<p>I found that often write<br>
Dir.mkdir(folder) unless Dir.exist? folder<br>
and similar code for rm, rm_rf and so on<br>
We can simply make bang-versions like<br>
def Dir.mkdir!(folder, permissions=0744)<br>
Dir.mkdir(folder, permissions) unless Dir.exist? folder</p>
<a name="or-another-alternative-Dirmkdirfolder-permissions-rescue-false"></a>
<h1 >or another alternative Dir.mkdir(folder, permissions) rescue false<a href="#or-another-alternative-Dirmkdirfolder-permissions-rescue-false" class="wiki-anchor">¶</a></h1>
<p>end</p> Ruby master - Feature #6810 (Assigned): `module A::B; end` is not equivalent to `module A; module...https://bugs.ruby-lang.org/issues/68102012-07-29T03:55:09Zalexeymuranov (Alexey Muranov)
<p>Is this the expected behavior? To me, it is rather surprising:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">N</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">module</span> <span class="nn">A</span>
<span class="k">module</span> <span class="nn">B</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">f</span><span class="p">;</span> <span class="no">N</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span>
<span class="no">N</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 1</span>
<span class="no">N</span> <span class="o">=</span> <span class="mi">0</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 0</span>
<span class="no">A</span><span class="o">::</span><span class="no">N</span> <span class="o">=</span> <span class="mi">1</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 1</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">N</span> <span class="o">=</span> <span class="mi">2</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 2</span>
</code></pre>
<p>but</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">N</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">module</span> <span class="nn">A</span><span class="p">;</span> <span class="k">end</span>
<span class="k">module</span> <span class="nn">A::B</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">f</span><span class="p">;</span> <span class="no">N</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">A</span>
<span class="no">N</span> <span class="o">=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 0</span>
<span class="no">N</span> <span class="o">=</span> <span class="mi">0</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 0</span>
<span class="no">A</span><span class="o">::</span><span class="no">N</span> <span class="o">=</span> <span class="mi">1</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 0</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="o">::</span><span class="no">N</span> <span class="o">=</span> <span class="mi">2</span>
<span class="no">A</span><span class="o">::</span><span class="no">B</span><span class="p">.</span><span class="nf">f</span> <span class="c1"># => 2</span>
</code></pre> Ruby master - Feature #6802 (Assigned): String#scan should have equivalent yielding MatchDatahttps://bugs.ruby-lang.org/issues/68022012-07-27T16:17:42Zprijutme4ty (Ilya Vorontsov)prijutme4ty@gmail.com
<p>Ruby should have method to obtain not an array of arrays but of MatchData objects. It can help in obtaining named groups:</p>
<p>pattern = /x: (?\d+) y:(?\d+)/<br>
polygon = []<br>
text.scan_for_pattern(pattern){|m| polygon << Point.new(m[:x], m[:y]) }</p>
<p>Not to break existing code we need unique name. Ideas? May be #each_match</p> Ruby master - Feature #6671 (Assigned): File.split_all and File.split_roothttps://bugs.ruby-lang.org/issues/66712012-06-30T04:28:57Ztrans (Thomas Sawyer)
<p>=begin<br>
Is there a method for this already?</p>
<p>File.split_all('a/b/c') #=> ['a','b','c']</p>
<p>If not I propose it be added. I've had need of such more than a few times.</p>
<p>It's too bad that File.split can't do this, as it would make more sense. And the current method be called <code>split_base</code>.</p>
<p>In addition <code>split_root</code> would be helpful.</p>
<p>root, path = File.split_all('a/b/c')<br>
root #=> 'a'<br>
path #=> 'b/c'<br>
=end</p> Ruby master - Feature #6648 (Assigned): Provide a standard API for retrieving all command-line fl...https://bugs.ruby-lang.org/issues/66482012-06-26T07:56:37Zheadius (Charles Nutter)headius@headius.com
<p>=begin<br>
Currently there are no standard mechanisms to get the flags passed to the currently running Ruby implementation. The available mechanisms are not ideal:</p>
<ul>
<li>Scanning globals and hoping they have not been tweaked to new settings</li>
<li>Using external wrappers to launch Ruby</li>
<li>???</li>
</ul>
<p>Inability to get the full set of command-line flags, including flags passed to the VM itself (and probably VM-specific) makes it impossible to launch subprocess Ruby instances with the same settings.</p>
<p>A real world example of this is "((%bundle exec%))" when called with a command line that sets various flags, a la ((%jruby -Xsome.vm.setting --1.9 -S bundle exec%)). None of these flags can propagate to the subprocess, so odd behaviors result. The only option is to put the flags into an env var (((|JRUBY_OPTS|)) or ((|RUBYOPT|))) but this breaks the flow of calling a simple command line.</p>
<p>JRuby provides mechanisms to get all its command line options, but they require calling Java APIs from Ruby's API set. Rubinius provides its own API for accessing comand-line options, but I do not know if it includes VM-level flags as well as standard Ruby flags.</p>
<p>I know there is a (({RubyVM})) namespace in the 2.0 line. If that namespace is intended to be general-purpose for VM-level features, it would be a good host for this API. Something like...</p>
<p>class << RubyVM<br>
def vm_args; end # returns array of command line args <em>not</em> passed to the target script</p>
<pre><code>def script; end # returns the script being executed...though this overlaps with $0
def script_args; end # returns args passed to the script...though this overlaps with ARGV, but that is perhaps warranted since ARGV can be modified (i.e. you probably want the original args)
</code></pre>
<p>end<br>
=end</p> Ruby master - Feature #6641 (Open): Hash.auto constructorhttps://bugs.ruby-lang.org/issues/66412012-06-25T09:34:06Ztrans (Thomas Sawyer)
<p>=begin<br>
It is not uncommon to need a Hash following the pattern:</p>
<p>Hash.new{ |h,k| h[k]={} }</p>
<p>Another common example:</p>
<p>Hash.new{ |h,k| h[k]=[] }</p>
<p>This is common enough that it would very nice if we could have a more concise form, e.g.</p>
<p>Hash.auto{ {} }</p>
<p>Or for the second example:</p>
<p>Hash.auto{ [] }</p>
<p>Pure Ruby implementation is pretty simple:</p>
<p>def Hash.auto<br>
Hash.new{ |h,k| h[k] = yield }<br>
end</p>
<p>I think it would be nice to have in Core.</p>
<p>This is secondary, but it just occurred to me. Could there even be a literal notation for the above? Something like:</p>
<p>{}([])</p>
<p>?<br>
=end</p> Ruby master - Feature #6596 (Assigned): New method `Array#indexes`https://bugs.ruby-lang.org/issues/65962012-06-15T18:05:05Zrobin850 (Robin Dupret)robin.dupret@gmail.com
<p>I submitted a pull request on Github that provides a new method <code>Array#indexes</code>. It departs from <code>Array#index</code> in such a way that it returns an array of indexes and not the single first occurrence that is relevant.</p>
<p>The reason I want this method is that I don't understand why <code>Array#index</code> returns a single index if the parameter is in the array several times.</p>
<p>Examples</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">indexes</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1">#=> [0, 3]</span>
<span class="n">a</span><span class="p">.</span><span class="nf">index</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => 0</span>
</code></pre>
<p>In my opinion, it's not logical to return only a single index since <code>1</code> is in the array twice.</p> Ruby master - Feature #6594 (Assigned): Integrated Functorhttps://bugs.ruby-lang.org/issues/65942012-06-15T09:02:38Ztrans (Thomas Sawyer)
<p>I know the developers meeting is coming up so I'd like to get a few ideas I've had sitting in the wings out in the air before then.</p>
<p>One the more useful is the idea of integrating Functors directly into the language. "Functor" is the term I use for "higher-order function".</p>
<p>I blogged about this idea and you can read it here: <a href="http://trans.github.com/2011-09-07-ruby-heart-higher-order-functions/" class="external">http://trans.github.com/2011-09-07-ruby-heart-higher-order-functions/</a></p>
<p>The super short version is this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">f</span> <span class="o">=></span> <span class="n">op</span><span class="p">,</span> <span class="n">arg</span>
<span class="n">arg</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">__op__</span><span class="p">,</span> <span class="n">arg</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">f</span> <span class="o">+</span> <span class="mi">3</span> <span class="c1">#=> 6</span>
<span class="n">f</span> <span class="o">*</span> <span class="mi">3</span> <span class="c1">#=> 9</span>
</code></pre>
<p>Another example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">String</span>
<span class="k">def</span> <span class="nf">file</span> <span class="o">=></span> <span class="n">op</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span>
<span class="no">File</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">__op__</span><span class="p">,</span> <span class="nb">self</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="s2">"README.rdoc"</span><span class="p">.</span><span class="nf">file</span><span class="p">.</span><span class="nf">mtime</span> <span class="c1">#=> 2012-06-14 12:34:45 -0400</span>
</code></pre>
<p>I'm using <code>=></code> as means of indicating a higher-order function. Of course another syntax could be used if this won't fly. The important thing is the idea of higher-order functions being integrated directly into the language. Doing this without that integration requires the creation of an intermediate object for each call which is very inefficient.</p> Ruby master - Feature #6445 (Assigned): request for default length/position on string indexhttps://bugs.ruby-lang.org/issues/64452012-05-17T13:02:30Zbotp (bot pena)botpena@gmail.com
<p>would be nice if ruby has default for "rest or up to end of string"</p>
<p>eg</p>
<p>"hello"[2,] => should default to "hello"[2..-1]<br>
or<br>
"hello"[2..] => should default to "hello"[2..-1]</p> Ruby master - Feature #6413 (Assigned): Make Dir.entries default to Dir.entries(Dir.pwd)https://bugs.ruby-lang.org/issues/64132012-05-08T22:12:34Zshevegen (Robert A. Heiler)shevegen@gmail.com
<p>Is there a reason why Dir.entries requires one argument?</p>
<p>I think it would be easier and more convenient for the userruby if it would default to the current directory. Like so:</p>
<p>Dir.entries(i = Dir.pwd)</p>
<p>Or is there a reason why this is not done?</p> Ruby master - Feature #6376 (Assigned): Feature lookup and checking if feature is loadedhttps://bugs.ruby-lang.org/issues/63762012-04-29T07:03:40Ztrans (Thomas Sawyer)
<p>$LOADED_FEATURES is useful to know what "files" have been loaded. But it doesn't really tell us what "features" have been loaded. If there where were a way to look-up a load path, without actually loading it then it would be possible to compare that to $LOADED_FEATURES and thus know. e.g.</p>
<pre><code>require 'ostruct'
$LOADED_FEATURES #=> [..., "/home/trans/.local/lib/ry/rubies/1.9.3-p125/lib/ruby/1.9.1/ostruct.rb"]
path = require_path('ostruct') #=> "/home/trans/.local/lib/ry/rubies/1.9.3-p125/lib/ruby/1.9.1/ostruct.rb"
$LOADED_FEATURES.include?(path)
</code></pre>
<p>Of course, it would be nice to also have:</p>
<pre><code>required?('ostruct') #=> true
</code></pre>
<p>These methods could be class methods of special module, if it's important to keep the Kernel more tidy, e.g. <code>Ruby.required?('ostruct')</code>.</p>
<p>I am currently working on a project where I need this (and have a couple of other projects that could use it too) and I've had to implement the whole thing from scratch, which isn't simple, nor fast, nor am I 100% confident that it specs exactly to Ruby's own lookup procedure. So it would be much better if Ruby would expose its lookup functionality.</p> Ruby master - Feature #6354 (Assigned): Remove escape (break/return/redo/next support) from class...https://bugs.ruby-lang.org/issues/63542012-04-25T12:12:17Zko1 (Koichi Sasada)
<p>Let's remove global escape (break/return/redo/next support) from class/module scope.</p>
<p>Yes, it introduces incompatibility. However, anyone use it?<br>
I think the following examples are evil (difficult to understand).</p>
<a name="examples"></a>
<h1 >examples:<a href="#examples" class="wiki-anchor">¶</a></h1>
<p>1.times{<br>
class C<br>
break # break from 1.times<br>
end<br>
}</p>
<p>1.times{<br>
class C<br>
module M<br>
break # break from 1.times<br>
end<br>
end<br>
}</p>
<p>3.times{|n|<br>
p n # repeat print 0<br>
class C<br>
redo<br>
end<br>
}</p>
<p>->{<br>
class C<br>
return return from outer lambda block<br>
end<br>
}.call</p>
<p>->{<br>
proc{<br>
class C<br>
return # return from outer lambda (not proc) block<br>
end<br>
}.call<br>
}.call</p>
<p>etc, etc.</p> Ruby master - Feature #6337 (Assigned): FileUtils#synchttps://bugs.ruby-lang.org/issues/63372012-04-22T09:13:25Ztrans (Thomas Sawyer)
<p>=begin<br>
I'd like to see some sort of FileUtils#sync method to sync the contents of one directory with another.</p>
<p>Here is a prototype definition:</p>
<pre><code>#
# Synchronize a destination directory with a source directory.
#
def sync(src, dst, options={})
src_files = Dir[File.join(src, '**', '*')].map{ |f| f.sub(src+'/', '') }
dst_files = Dir[File.join(dst, '**', '*')].map{ |f| f.sub(dst+'/', '') }
removal = dst_files - src_files
rm_dirs, rm_files = [], []
removal.each do |f|
path = File.join(dst, f)
if File.directory?(path)
rm_dirs << path
else
rm_files << path
end
end
rm_files.each { |f| rm(f) }
rm_dirs.each { |d| rmdir(d) }
src_files.each do |f|
src_path = File.join(src, f)
dst_path = File.join(dst, f)
if File.directory?(src_path)
mkdir_p(dst_path)
else
parent = File.dirname(dst_path)
mkdir_p(parent) unless File.directory?(parent)
install(src_path, dst_path)
end
end
end
</code></pre>
<p>I haven't tested this beyond a simple trial. It needs improvement. For one, it probably should be able to handle regular files as arguments too. It also needs to handle verbose and dryrun options properly. Nonetheless, with improvements, would be okay for such to become new feature for FileUtils?</p>
<p>=end</p> Ruby master - Feature #6317 (Assigned): Range#cover?の引数としてRangeインスタンスを受けられるようにして欲しいhttps://bugs.ruby-lang.org/issues/63172012-04-18T20:51:08Zmasaakiaoyagi (Masaaki Aoyagi)masaaki.aoyagi@gmail.com
<p>青柳と申します。</p>
<p>以下のように、Range#cover?の引数としてRangeインスタンスを<br>
受けられるようにして欲しいです。<br>
(1..4).cover?(2..3) # => true<br>
(1..4).cover?(0..3) # => false</p>
<p>取り敢えず実装してみましたので、添付いたします。</p> Ruby master - Feature #6308 (Assigned): Eliminate delegation from WeakRefhttps://bugs.ruby-lang.org/issues/63082012-04-17T17:02:28Zheadius (Charles Nutter)headius@headius.com
<p>WeakRef's delegation features are a really awful pattern that should not be allowed in future versions of Ruby.</p>
<p>WeakRef makes no guarantees as to the liveness of its contained object. It can be collected at any time if there are no strong references to it.</p>
<p>WeakRef currently uses delegation to pass method calls through to the contained object. This encourages a pattern where a WeakRef is passed to methods that expect to have a reference to the underlying object, making it appear to be that object.</p>
<p>Unfortunately, this is <em>never</em> a good idea. Because the object can be collected at any time, you may get a nil reference from <strong>getobj</strong> <em>arbitrarily</em> in code that tries to call methods against the given WeakRef. That means using WeakRef as a delegate will always result in unreliable code, and errors may happen for inexplicable reasons.</p>
<p>I believe Ruby 2.0 should eliminate WeakRef's delegation features and make it a simple reference holder. There's no safe way to use a weak reference except to grab a reference to the object, check that it is alive (non-nil) and then proceed with the use of the object, as follows:</p>
<p>obj = weakref.<strong>getobj</strong><br>
raise AppropriateError unless obj<br>
obj.do_something<br>
obj.do_something_else</p>
<p>Along with eliminating delegation, I would recommend simply making the get method #get, since the uglier #<strong>getobj</strong> is only named that way because it is not delegated.</p> Ruby master - Feature #6293 (Assigned): new queue / blocking queueshttps://bugs.ruby-lang.org/issues/62932012-04-14T08:28:58Ztenderlovemaking (Aaron Patterson)tenderlove@ruby-lang.org
<p>Hi,</p>
<p>I'd like to add new Queue objects to ruby. Whenever I use queues, I either use them in a blocking or non-blocking manner only, so I have separated them in to two classes Thread::Queue, and Thread::BlockingQueue.</p>
<p>Other notable differences, these queues:</p>
<ul>
<li>implement <code>poll</code>, which will return a nil if the queue is empty</li>
<li>do not allow <code>nil</code> to be in the queue as it would interfere with <code>poll</code>
</li>
<li>include Enumerable</li>
</ul>
<p>I think these will be a good basis for implementing a Deque, SynchronizedQueue, and PriorityQueue.</p>
<p>I've attached a patch against trunk.</p> Ruby master - Feature #6277 (Assigned): Hash#convert_keyhttps://bugs.ruby-lang.org/issues/62772012-04-11T01:12:20Ztrans (Thomas Sawyer)
<p>=begin<br>
Many times a hash with uniform keys is needed (or is at least preferable) for a particular usecase. To this end I propose ((%Hash#convert_key%)).</p>
<p>h = {}<br>
h.convert_key{ |k| k.to_sym }<br>
h['a'] = 1<br>
h.update('b'=>2)<br>
h #=> {:a=>1, :b=>2}</p>
<p>The idea is similar in concept to ((%#default_proc%)).</p>
<p>Others solutions to fill this need have been tried and used, but almost exclusively are in the form of a new class. Most notable is Rails HashWithIndifferentAccess. But ((%#convert_key%)) has much greater flexibility since keys can be converted to anything.<br>
=end</p> Ruby master - Feature #5825 (Assigned): Sweet instance var assignment in the object initializerhttps://bugs.ruby-lang.org/issues/58252011-12-30T22:49:03Zgoshakkk (Gosha Arinich)me@goshakkk.name
<p>I'm very excited about this feature in CoffeeScript, and think it might be a nice-to-have thing in Ruby 2.0.</p>
<p>That's how I think it would look like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Me</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">@location</span><span class="p">);</span> <span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>So we can declare <code>@variable</code>s in the initializer method parameters definition to avoid assigning instance variables from method arguments by hand, like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Me</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">location</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">@location</span> <span class="o">=</span> <span class="n">location</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Want to hear what do you guys think, does that feature worth being included in 2.0?</p> Ruby master - Feature #5781 (Assigned): Query attributes (attribute methods ending in `?` mark)https://bugs.ruby-lang.org/issues/57812011-12-20T04:57:11Ztrans (Thomas Sawyer)
<p>Pretty sure this has come up before, but I'd like to revisit b/c I don't understand why it isn't allowed.</p>
<p>Sometimes I define "query" attributes, and in those cases I'd like the reader method to end in a <code>?</code> mark. Currently I have to do:</p>
<pre><code># @attribute
def foo?
@foo
end
</code></pre>
<p>or, if I don't mind a shadowing bare method,</p>
<pre><code>attr :foo
alias_method :foo?, :foo
</code></pre>
<p>So why not just allow:</p>
<pre><code>attr :foo?
</code></pre>
<p>Currently this causes an error. But why? It just seems like a waste of potentially cleaner code.</p> Ruby master - Feature #5749 (Assigned): new method String#match_all neededhttps://bugs.ruby-lang.org/issues/57492011-12-12T18:03:57Zyimutang (Joey Zhou)
<p>The String class should contain an instance method 'match_all', which is a mixture of 'match' and 'scan'.</p>
<p>The method 'scan' is not a very powerful tool, its result(the yielding thing) is just a matched string or an array of captured strings.</p>
<p>p 'a1bc2de3f'.scan(/(.)\d(.)/) # [["a", "b"], ["c", "d"], ["e", "f"]]</p>
<p>If the regex argument contains groups, I even cannot get the whole matched string, and no information about the matched offsets.</p>
<p>So, a 'match_all' is very necessary. It scan the string, finding every matched, and yielding <em>MatchData instance</em> to the following block.</p>
<p>Here's a simple implemention in Ruby:</p>
<p>class String<br>
def match_all(re,i=0)<br>
if block_given?<br>
while m = self.match(re,i)<br>
yield m<br>
i = m.end(0)<br>
end<br>
return self<br>
else<br>
ary = []<br>
while m = self.match(re,i)<br>
ary << m<br>
i = m.end(0)<br>
end<br>
return ary<br>
end<br>
end<br>
end</p>
<p>However, it is not efficient in the 'while m = self.match(re,i)' way, because it scan the string again and again. If string is UTF8-encoded and contains out-of-ASCII characters, I'm afraid getting the start index of it is so expensive.</p>
<p>So, I think a built-in 'match_all' method, which behaves just like 'scan' but yield MatchData, is needed.</p>
<p>Please consider it, thank you!</p> Ruby master - Feature #5741 (Assigned): Secure Erasure of Passwordshttps://bugs.ruby-lang.org/issues/57412011-12-11T06:02:13ZMartinBosslet (Martin Bosslet)Martin.Bosslet@gmail.com
<p>In other languages it is considered good practice to securely erase<br>
passwords immediately after they were used. Imagine authentication<br>
in a web app - ultimately a String containing the password arrives<br>
at the server, where it will be processed and compared to some<br>
previously stored value. After this is done, there is no need to<br>
store these password Strings any longer, so they should be<br>
discarded right away (more on why later).</p>
<p>In C, you would simply overwrite the array of bytes with zeroes or<br>
random values. In Java, Strings are immutable, that's why there it<br>
is common practice to use char[] for all things password and overwrite<br>
them when done.</p>
<p>Currently, there is no way in Ruby to overwrite the memory that<br>
was used by a String. String#clear and String#replace both use<br>
str_discard internally, which only frees the underlying pointer<br>
without overwriting it.</p>
<p>The problem with not erasing passwords is this: the contents of the<br>
String stay in memory until they are finally GC'ed. But even then<br>
only the pointer will be freed, leaving the contents mostly intact<br>
until the memory is reclaimed and overwritten later on.</p>
<p>This could be exploited if an attacker had access to the memory of<br>
the server. This could happen in many ways: a core dump after a<br>
crash, access to the host if the server runs in a VM, or even by<br>
deep-freezing the DRAM :) [1]</p>
<p>It could be argued that given the examples above, much more<br>
devastating attacks would be possible since in all of those<br>
cases you more or less have physical access to the machine. But<br>
I would still consider this to be a valid concern, if not only<br>
for the reason of never opening additional attack surfaces if<br>
they can be avoided relatively easily.</p>
<p>I also found [2], which seems to show that Python deals with<br>
similar problems and it also contains more background info.</p>
<p>Eric Hodel and I discussed this yesterday and Eric came up with<br>
a C extension that can be used to illustrate the problem (attached).</p>
<p>If you inspect the resulting core dump, you will find the following:</p>
<ul>
<li>the untouched String remains in memory fully intact</li>
<li>the String#clear'ed String remains to a large extent, typically the<br>
first character is missing - so if you typed "PASSWORD", search for<br>
"ASSWORD" (unintentional pun) instead</li>
<li>The String#clear_secure'ed will have been completely erased, no<br>
traces remain</li>
</ul>
<p>My questions:</p>
<ol>
<li>Would you agree that we need this functionality?</li>
<li>Where would we ideally place it? I'm not sure whether<br>
String is the perfect place, but on the other hand, String<br>
is the only place where we have access to the implementation<br>
details.</li>
<li>Are there better alternative ways how we could achieve this?</li>
</ol>
<p>[1] <a href="http://www.schneier.com/blog/archives/2008/02/cold_boot_attac.html" class="external">http://www.schneier.com/blog/archives/2008/02/cold_boot_attac.html</a><br>
[2] <a href="http://stackoverflow.com/questions/728164/securely-erasing-password-in-memory-python" class="external">http://stackoverflow.com/questions/728164/securely-erasing-password-in-memory-python</a></p> Ruby master - Feature #5643 (Assigned): require/load options and binding optionhttps://bugs.ruby-lang.org/issues/56432011-11-17T07:41:01Ztrans (Thomas Sawyer)
<p>Current Kernel#load is defined as:</p>
<pre><code>load(filename, wrap=false)
</code></pre>
<p>I purpose that it be modified to work as option argument, e.g.</p>
<pre><code>load(filename, :wrap=>true)
</code></pre>
<p>Right off the bat this has better name connascence.</p>
<p>Then support an additional option <code>:binding</code>, such that, given:</p>
<pre><code>$ cat lib/example.rb
def a
1
end
</code></pre>
<p>then</p>
<pre><code>class X
load('example.rb', :binding=>binding)
end
X.new.a #=> 1
</code></pre>
<p>The binding option should also work with #require (which would also support option parameter) differing from #load in the it would only allow the feature to be loaded once per-binding's self regardless of being required again.</p>
<p>This ability would greatly benefit systems that need "plugin" capability. Presently, a great deal of coding has to go into simulating this functionality to create plugin systems, which are often imperfect nor robust.</p> Ruby master - Feature #5558 (Assigned): String#% strange arity errorshttps://bugs.ruby-lang.org/issues/55582011-11-03T10:25:55Ztrans (Thomas Sawyer)
<p>When the number of arguments do not match the number of % parameters, the String#% method has some odd behavior.</p>
<p>When too many, it seems to work fine, ignoring the extra arguments.</p>
<p>"%s" % [1,2] #=> "1"</p>
<p>But if <code>$DEBUG = true</code>,</p>
<p>"%s" % [1,2] #=> ArgumentError: too many arguments for format string</p>
<p>That doesn't seem right. Is it an error or isn't it?</p>
<p>For too few arguments it is always an error:</p>
<p>"%s" % [] #=> ArgumentError: too few arguments</p>
<p>Personally, I think it should use '' for missing arguments. That would make it more flexible in practice.</p>
<p>I consider the first $DEBUG issue a bug, and the later a feature. But I'll just call it a feature altogether to make things easier.</p> Ruby master - Feature #5456 (Assigned): kernel#syscall() should be removed.https://bugs.ruby-lang.org/issues/54562011-10-18T04:06:16Zkosaki (Motohiro KOSAKI)kosaki.motohiro@gmail.com
<p>It doesn't works correctly a long time. It's not portable and JRuby have no chance to implement it.<br>
Moreover, Fiddle provides better interface.</p> Ruby master - Feature #5445 (Assigned): Need RUBYOPT -r before ARGV -rhttps://bugs.ruby-lang.org/issues/54452011-10-14T00:47:09Ztrans (Thomas Sawyer)
<p>Libraries given by -r options in RUBYOPT should be loaded before ones in direct command line arguments.</p>
<p>I use a custom load system for development that I have been using for years and it works very well for me. But Ruby has some edge cases that prevents it from being feature complete. One of these is the order in which RUBYOPT is applied vs. -r command line option.</p>
<p>My custom loader is too large to include here, so I will simply demonstrate the problem with simple sample code:</p>
<p>$ cat req.rb<br>
p "Custom Require"</p>
<p>module Kernel<br>
alias :require0 :require</p>
<pre><code>def require(*a)
puts "Kernel#require"
p a
require0(*a)
end
class << self
alias :require0 :require
def require(*a)
puts "Kernel.require"
p a
require0(*a)
end
end
</code></pre>
<p>end</p>
<p>If we load this via RUBYOPT, the result is:</p>
<p>$ RUBYOPT=-r./req.rb ruby -rstringio -e0<br>
Custom Require</p>
<p>But if we load via -r the result is:</p>
<p>$ ruby -r./req.rb -rstringio -e0<br>
Custom Require<br>
Kernel#require<br>
["stringio"]</p>
<p>I would ask that the output of both invocations to be identical.</p>
<p>(Note, the -T option should still allow RUBYOPT to be omitted regardless.)</p> Ruby master - Feature #5389 (Assigned): New method Enumerator#iteratehttps://bugs.ruby-lang.org/issues/53892011-10-03T20:25:16Zyimutang (Joey Zhou)
<p>If we want to iterate over the elements of a enumerable object with <em>multiple</em> blocks, we can use the Enumerator class.</p>
<p>A method 'iterate' is required, we can write it in Ruby:</p>
<pre><code>class Enumerator
def iterate
yield_value = self.next
return_value = yield yield_value
self.feed return_value
self
end
end
</code></pre>
<p>Well, here is an example:</p>
<pre><code>array = (1..10).to_a
enum = array.map!
loop do
enum.iterate {|n| n + 10 }
enum.iterate {|n| n * 2 }
enum.iterate {|n| -n }
end
p array # => [11, 4, -3, 14, 10, -6, 17, 16, -9, 20]
</code></pre>
<p>We want to map an array: the 1st element use blk1, the 2nd use blk2, the 3rd use blk3...</p>
<p>I think this Enumerator#iterate method is sometimes useful, so would you please introduce it into the language core?</p> Ruby master - Feature #5064 (Assigned): HTTP user-agent classhttps://bugs.ruby-lang.org/issues/50642011-07-21T13:10:00Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>Currently there are some problems with Net::HTTP:</p>
<ul>
<li>Too many ways to use (user confusion)</li>
<li>No automatic support for HTTPS (must conditionally set use_ssl)</li>
<li>No automatic support for HTTPS peer verification (must be manually set)</li>
<li>Single-connection oriented</li>
<li>No support for redirect-following</li>
<li>No support for HTTP/1.1 persistent connection retry (RFC 2616 8.1.4)</li>
<li>No automatic support for HTTP proxies</li>
<li>No automatic support for authentication (must be set per-request)</li>
</ul>
<p>Additionally the style of the API of Net::HTTP makes it difficult to take advantage of persistent connections. The user has to store the created connection and manually handle restarting the connection if it has timed out or is closed by the server.</p>
<p>RFC 2616 8.1.1 has a large section explaining the benefits of persistent connections, but while Net::HTTP implements persistent connections they could be easier for users to implement with next work.</p>
<p>I've implemented support for many of these additional features of Net::HTTP in various projects and I'd like Ruby to have the features required to make a useful HTTP user-agent built-in.</p>
<p>The agent should have the following responsibilities:</p>
<ul>
<li>Make or reuse connections based on [host, port, SSL enabled]</li>
<li>Automatically enable SSL for https URIs</li>
<li>Automatically enable SSL peer verification for SSL connections</li>
<li>Limit number of persistent connections per host</li>
<li>Follow redirects</li>
<li>Retry when a persistent connection fails</li>
<li>Automatically configure proxies</li>
<li>Automatically use authentication</li>
<li>Callbacks for various options connect</li>
</ul>
<p>The agent may add the following responsibilities:</p>
<ul>
<li>Default headers for all requests</li>
<li>HTTP cookies</li>
<li>Tracking history</li>
<li>Logging</li>
</ul>
<p>I don't think any of these features are critical as they are implementable by users via callbacks.</p>
<p>The agent would have the following configurable items:</p>
<ul>
<li>Number of connections per host</li>
<li>Depth of redirects followed</li>
<li>Persistent connection retries (none, HTTP/1.1 (default), always)</li>
<li>Proxy host, port, user, password</li>
</ul>
<p>I think the class should be called Net::HTTP::Agent.</p>
<p>Basic use would look something like this:</p>
<p>uris = [<br>
URI('http://example/1'),<br>
URI('http://example/2'),<br>
URI('https://secure.example'),<br>
]</p>
<p>agent = Net::HTTP::Agent.new</p>
<p>uris.map do |uri|<br>
agent.get uri # Returns Net::HTTPResponse<br>
end</p>
<p>For special requests a Net::HTTPRequest could be constructed:</p>
<p>req = Net::HTTP::Get.new uri.request_uri</p>
<a name="do-something-special-with-req"></a>
<h1 >do something special with req<a href="#do-something-special-with-req" class="wiki-anchor">¶</a></h1>
<p>agent.request req</p>
<p>The agent should support GET, POST, etc. directly through API methods. I think the API should look something like this:</p>
<p>def get uri_or_string, query = nil, headers = nil</p>
<a name="Same-for-other-requests-with-no-body"></a>
<h1 >Same for other requests with no body<a href="#Same-for-other-requests-with-no-body" class="wiki-anchor">¶</a></h1>
<h1></h1>
<a name="query-may-be-a-Hash-or-String"></a>
<h1 >query may be a Hash or String<a href="#query-may-be-a-Hash-or-String" class="wiki-anchor">¶</a></h1>
<a name="How-query-param-vs-query-string-in-URI-is-used-is-undecided"></a>
<h1 >How query param vs query string in URI is used is undecided<a href="#How-query-param-vs-query-string-in-URI-is-used-is-undecided" class="wiki-anchor">¶</a></h1>
<p>def post uri_or_string, data, headers = nil</p>
<a name="same-for-other-requests-with-a-body"></a>
<h1 >same for other requests with a body<a href="#same-for-other-requests-with-a-body" class="wiki-anchor">¶</a></h1>
<h1></h1>
<a name="data-may-be-a-String-IO-or-Hash"></a>
<h1 >data may be a String, IO or Hash<a href="#data-may-be-a-String-IO-or-Hash" class="wiki-anchor">¶</a></h1>
<a name="How-data-format-is-chosen-is-undecided"></a>
<h1 >How data format is chosen is undecided<a href="#How-data-format-is-chosen-is-undecided" class="wiki-anchor">¶</a></h1>
<p>SSL options, proxy options, timeouts and similar options should exist on Net::HTTP::Agent and be set on new connections as they are made.</p>
<p>I've implemented most of these features in mechanize as Mechanize::HTTP::Agent. The Agent class in mechanize is bigger than is necessary and would need to be cut-down for inclusion in Ruby as Net::HTTP::Agent</p>
<p><a href="https://github.com/tenderlove/mechanize/blob/master/lib/mechanize/http/agent.rb" class="external">https://github.com/tenderlove/mechanize/blob/master/lib/mechanize/http/agent.rb</a></p>
<p>Mechanize depends on net-http-persistent to provide HTTP/1.1 retry support and connection management:</p>
<p><a href="https://github.com/drbrain/net-http-persistent/blob/master/lib/net/http/persistent.rb" class="external">https://github.com/drbrain/net-http-persistent/blob/master/lib/net/http/persistent.rb</a></p>
<p>Portions of net-http-persistent should be patches of Net::HTTP, for example #idempotent? #can_retry?, #reset and portions of #request. Other parts (connection management) should be moved to Net::HTTP::Agent.</p>
<p>net-http-persistent provides a separate connection list per thread. I would like Net::HTTP::Agent to be multi-thread friendly but implementing this in another way would be fine.</p>
<p>As an addendum, open-uri and mechanize should be written to take advantage of Net::HTTP::Agent on order to guide useful implementation.</p> Ruby master - Feature #5007 (Assigned): Proc#call_under: Unifying instance_eval and instance_exechttps://bugs.ruby-lang.org/issues/50072011-07-09T23:26:49Zjudofyr (Magnus Holm)judofyr@gmail.com
<p>I'm proposing a method called <code>Proc#call_under</code> (the name could be<br>
discussed) which both unifies <code>instance_eval</code> and <code>instance_exec</code>, and makes<br>
it possible to call a <code>Proc</code> with a block and a scope:</p>
<p><code>Proc#call_under(self, *args, &blk)</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">proc</span> <span class="p">{</span> <span class="nb">self</span> <span class="p">}.</span><span class="nf">call_under</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="c1"># => 1</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="nb">self</span> <span class="o">+</span> <span class="n">a</span> <span class="p">}.</span><span class="nf">call_under</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="c1"># => 3</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="o">|&</span><span class="n">b</span><span class="o">|</span> <span class="nb">self</span> <span class="o">+</span> <span class="n">b</span><span class="p">.</span><span class="nf">call</span> <span class="p">}.</span><span class="nf">call_under</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="p">{</span> <span class="mi">2</span> <span class="p">}</span> <span class="c1"># => 4</span>
</code></pre> Ruby master - Feature #4824 (Assigned): Provide method Kernel#executed?https://bugs.ruby-lang.org/issues/48242011-06-04T19:59:21Zlazaridis.com (Lazaridis Ilias)ilias@lazaridis.com
<p>The current construct to execute main code looks not very elegant:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="kp">__FILE__</span> <span class="o">==</span> <span class="vg">$0</span>
<span class="n">my_main</span><span class="p">()</span> <span class="c1"># call any method or execute any code</span>
<span class="k">end</span>
</code></pre>
<p>With a <code>Kernel#executed?</code> method, this would become more elegant:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">if</span> <span class="n">executed?</span>
<span class="c1">#do this</span>
<span class="c1">#do that</span>
<span class="n">my_main</span><span class="p">()</span>
<span class="k">end</span>
</code></pre>
<p>or</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">main</span><span class="p">()</span> <span class="k">if</span> <span class="n">executed?</span>
</code></pre>
<p>This addition would not break any existent behaviour.</p> Ruby master - Feature #4592 (Assigned): Tempfileを直接保存したいhttps://bugs.ruby-lang.org/issues/45922011-04-21T16:43:31Zxibbar (Takeyuki FUJIOKA)xibbar@gmail.com
<p>=begin<br>
Tempfileは一時ファイルなので、プロセスが消えたり、#closeすると、<br>
ファイルが消えてしまいます。<br>
Tempfileのデータを保存するために<br>
一旦読みだして、書き込み用に別ファイルを開いて、<br>
そこに書きこまなければいけません。<br>
これが小さいファイルだったらいいのですが、<br>
大きいファイルになると、<br>
Tempfile#save みたいなメソッドを用意して、<br>
closeと同時に保存ができると、<br>
読みだして書きこむという無駄をなくすことができます。<br>
10MB程度だったらいいのですが、500MとかのTempfileだと<br>
かなり有効なメソッドだと思います。</p>
<p>#save とか #save! とか、何がいいかは議論の余地があると思います。<br>
=end</p> Ruby master - Feature #4521 (Assigned): NoMethodError#message may take very long to executehttps://bugs.ruby-lang.org/issues/45212011-03-25T04:59:14Zadiel.mittmann (Adiel Mittmann)adiel@inf.ufsc.br
<p>=begin<br>
When a non-existing method is called on an object, NoMethodError is risen. If you call #message, however, your code may use up all CPU for a very long time (in my case, up to a few minutes).</p>
<p>I narrowed the problem down to this code in error.c (SVN snapshot) in the function name_err_mesg_to_str():</p>
<p>d = rb_protect(rb_inspect, obj, 0);<br>
if (NIL_P(d) || RSTRING_LEN(d) > 65) {<br>
d = rb_any_to_s(obj);<br>
}</p>
<p>The problem is that, for a complex object, #inspect may take very long to execute, only to have its results thrown away because they will be larger than 65 characters.</p>
<p>Of course I can write a #to_s for all my objects, but the point is that I didn't call #to_s or #inspect, I called #message on an exception object, which then takes a few minutes just to return a short string.</p>
<p>Needless to say, this might be easy to spot in a simple example, but once you're writing a web application that suddenly freezes for one minute with no apparent reason, you're all but clueless as to what's going on. (The first time this happened, I didn't even know that something would eventually show up on the screen -- I thought it was an infinite loop).</p>
<p>Here's an example code that shows this behavior:</p>
<p>require 'nokogiri'<br>
class A<br>
def x<br>
@xml = Nokogiri::XML(File.new('baz.xml', 'rb').read())<br>
foo()<br>
end<br>
end<br>
A.new().x()<br>
a.x</p>
<p>Here, the time it takes for Ruby to print out the message that #foo doesn't exist is proportional to the size of baz.xml.</p>
<p>As a comparison, Python doesn't seem to do this. Take the following code:</p>
<p>class Test:<br>
def <strong>str</strong>(self):<br>
return "hello"<br>
a = Test()<br>
print a<br>
print a.x()</p>
<p>If you execute it, this is the result:</p>
<p>hello<br>
Traceback (most recent call last):<br>
File "test.py", line 6, in <br>
print a.x()<br>
AttributeError: Test instance has no attribute 'x'</p>
<p>It uses the method <strong>str</strong> to convert the object to a string when necessary, but doesn't use it when printing out the message stating that the attribute doesn't exist.</p>
<p>One obvious way to fix this would be to always print out the simpler representation given by rb_any_to_s.<br>
=end</p>