Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112022-10-15T03:04:07ZRuby Issue Tracking System
Redmine Ruby master - Feature #19059 (Open): Introduce top level `module TimeoutError` for aggregating va...https://bugs.ruby-lang.org/issues/190592022-10-15T03:04:07Zioquatix (Samuel Williams)samuel@oriontransfer.net
<p>This proposal was originally part of <a href="https://bugs.ruby-lang.org/issues/18630" class="external">https://bugs.ruby-lang.org/issues/18630</a> but was removed because we could not decide on the name.</p>
<p>Introduce the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">TimeoutError</span>
<span class="k">end</span>
<span class="no">IO</span><span class="o">::</span><span class="no">TimeoutError</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
<span class="no">Regexp</span><span class="o">::</span><span class="no">TimeoutError</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
<span class="c1"># Maybe?</span>
<span class="no">Timeout</span><span class="o">::</span><span class="no">Error</span><span class="p">.</span><span class="nf">include</span><span class="p">(</span><span class="no">TimeoutError</span><span class="p">)</span>
</code></pre>
<p>It may be easier for users.</p>
<p>This was discussed before with the following conclusion:</p>
<ul>
<li>Top level <code>TimeoutError</code> is available.</li>
<li>Using a module for a <code>TimeoutError</code> may not be consistent with other top level <code>class #{thing}Error</code>.</li>
</ul> Ruby master - Feature #17849 (Open): Fix Timeout.timeout so that it can be used in threaded Web s...https://bugs.ruby-lang.org/issues/178492021-05-05T01:41:09Zduerst (Martin Dürst)duerst@it.aoyama.ac.jp
<p>Making this a separate issue from <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Add support for Regexp timeouts (Closed)" href="https://bugs.ruby-lang.org/issues/17837">#17837</a></p>
<p>Eregon (Benoit Daloze) wrote in <a href="https://bugs.ruby-lang.org/issues/17837#note-10" class="external">https://bugs.ruby-lang.org/issues/17837#note-10</a> (which is about timeouts for regular expressions):</p>
<blockquote>
<p>I think fixing Timeout.timeout might be possible.<br>
The main/major issue is it can trigger within <code>ensure</code>, right? Is there anything else?<br>
We could automatically mask <code>Thread#raise</code> within <code>ensure</code> so it only happens after the <code>ensure</code> body completes.<br>
And we could still have a larger "hard timeout" if an <code>ensure</code> takes way too long (shouldn't happen, but one cannot be sure).<br>
I recall discussing this with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/6346">@schneems (Richard Schneeman)</a> some time ago on Twitter.</p>
</blockquote> Ruby master - Feature #17830 (Open): Add Integer#previous and Integer#prev https://bugs.ruby-lang.org/issues/178302021-04-26T17:27:05Zrafasoares (Rafael Soares)rafasoaresms@gmail.com
<p>I think <code>Integer#pred</code> is great as the inverse of <code>#succ</code>, but it reads a bit weird as the inverse of <code>#next</code>, which might be preferable for those going for a more "reads like English" approach.</p>
<p>On that note, <code>#previous</code> reads better, but it's also twice as long as <code>#pred</code> (or even <code>#next</code>). Which is why I've also added the shorthand <code>#prev</code></p>
<p>Since Ruby strives for readability, I always thought it was weird that the team omitted this improvement.</p>
<p>Also, I thought about writing a gem for this, but:</p>
<ol>
<li>Do we really want to add another gem for such a simple change to every project?</li>
<li>Monkey-patching gems feel dirty.</li>
</ol>
<p>Finally, I want to mention that I tried looking for previous discussions on this topic, as it seems likely someone would've brought this up at some point, but was unsuccessful. Probably due to the massive amount of baggage in the core issue tracker and mailing lists, I could've missed something among the noise.</p>
<p>I've created a fork on GitHub (<a href="https://github.com/rafasoares/ruby/commit/05119848b1f480db2e809f964528799030cc7ebb" class="external">https://github.com/rafasoares/ruby/commit/05119848b1f480db2e809f964528799030cc7ebb</a>) in order to open a PR, but decided to open this ticket as well, after reading the contributing guide more carefully.</p> Ruby master - Feature #17785 (Open): Allow named parameters to be keywordshttps://bugs.ruby-lang.org/issues/177852021-04-08T15:08:40Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>We should allow named parameters to be keywords and use add a trailing <code>_</code> to the corresponding variable:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="k">class</span><span class="p">:)</span>
<span class="n">arg</span><span class="p">.</span><span class="nf">is_a?</span><span class="p">(</span><span class="n">class_</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">check</span><span class="p">(</span><span class="mi">42</span><span class="p">,</span> <span class="ss">class: </span><span class="no">Integer</span><span class="p">)</span> <span class="c1"># => true</span>
</code></pre>
<p>Currently, if we want such an API we have to use <code>**rest</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">check</span><span class="p">(</span><span class="n">arg</span><span class="p">,</span> <span class="o">**</span><span class="n">rest</span><span class="p">)</span>
<span class="n">class_</span> <span class="o">=</span> <span class="n">rest</span><span class="p">.</span><span class="nf">fetch</span><span class="p">(</span><span class="ss">:class</span><span class="p">)</span> <span class="p">{</span> <span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">(</span><span class="s1">'missing keyword: :class'</span><span class="p">)}</span>
<span class="k">if</span> <span class="n">rest</span><span class="p">.</span><span class="nf">size</span> <span class="o">></span> <span class="mi">1</span>
<span class="n">unknown</span> <span class="o">=</span> <span class="n">rest</span><span class="p">.</span><span class="nf">keys</span> <span class="o">-</span> <span class="p">[</span><span class="ss">:class</span><span class="p">]</span>
<span class="k">raise</span> <span class="no">ArgumentError</span><span class="p">(</span><span class="s2">"unknown keyword(s): :</span><span class="si">#{</span><span class="n">unknown</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="s1">', :'</span><span class="p">)</span><span class="si">}</span><span class="s2">)
end
arg.is_a?(class_)
end
</span></code></pre>
<p>This is very verbose, much less convenient, much less readable, prevents <code>steep</code> from generating the proper signature, etc.</p>
<p>We should do the same for pattern match.</p> Ruby master - Feature #17291 (Assigned): Optimize __send__ callhttps://bugs.ruby-lang.org/issues/172912020-10-29T03:05:45Zmrkn (Kenta Murata)muraken@gmail.com
<p>I made a patch to optimize a <code>__send__</code> call. This optimization replaces a <code>__send__</code> method call with a call of the method whose name is the first argument of <code>__send__</code> method. The patch is available in <a href="https://github.com/ruby/ruby/pull/3720" class="external">this pull-request</a>.</p>
<p>By this change, the redefined <code>__send__</code> method is no longer called when it is called by a symbol method name. I guess it is no problem because the following warning message is displayed for a long time.</p>
<pre><code>$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
</code></pre>
<p>This proposal introduces two new instructions: <code>sendsym</code> and <code>opt_sendsym_without_block</code>. These instructions handle the cases that the first argument of <code>__send__</code> method is not a symbol literal. I think I can combine these two instructions into one if prefered.</p>
<p>This proposal includes the change proposed in <a class="issue tracker-2 status-1 priority-4 priority-default" title="Feature: Optimize __send__ call with a literal method name (Open)" href="https://bugs.ruby-lang.org/issues/17288">#17288</a>. I'll mark it as a duplicate of this proposal.</p>
<p>I don't handle <code>send</code> method in this proposal. The reason is that we need to examine the redefinition of <code>send</code> method in the instruction execution time. I want to discuss only <code>__send__</code> method in this ticket.</p>
<p>The benchmark result is below:</p>
<pre><code># Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:----------------|-----------:|---------:|
|vm_send_sym | 18.001M| 112.208M|
| | -| 6.23x|
|vm_send_var | 17.779M| 30.922M|
| | -| 1.74x|
|vm_send_var_alt | 3.817M| 6.817M|
| | -| 1.79x|
</code></pre> Ruby master - Feature #17288 (Open): Optimize __send__ call with a literal method namehttps://bugs.ruby-lang.org/issues/172882020-10-27T08:32:40Zmrkn (Kenta Murata)muraken@gmail.com
<p>I made a patch to optimize a <code>__send__</code> call with a literal method name. This optimization replaces a <code>__send__</code> method call with a <code>send</code> instruction. The patch is available in <a href="https://github.com/ruby/ruby/pull/3707" class="external">this pull-request</a>.</p>
<p>By this change, the redefined <code>__send__</code> method is no longer called when it is called by a literal method name. I guess it is no problem because the following warning message is displayed for a long time.</p>
<pre><code>$ ruby -e 'def __send__; end'
-e:1: warning: redefining `__send__' may cause serious problems
</code></pre>
<p>This change makes the optimized case x5~x6 faster. The benchmark result is below:</p>
<pre><code>$ make benchmark COMPARE_RUBY="../../ruby/build-o3/ruby" ITEM=vm_send.yml
(snip)
# Iteration per second (i/s)
| |compare-ruby|built-ruby|
|:------------|-----------:|---------:|
|vm_send | 18.536M| 113.778M|
| | -| 6.14x|
|vm_send_var | 18.085M| 16.595M|
| | 1.09x| -|
</code></pre> Ruby master - Feature #17279 (Open): Allow a negative step in Range#step with a blockhttps://bugs.ruby-lang.org/issues/172792020-10-22T02:23:48Zmrkn (Kenta Murata)muraken@gmail.com
<p><code>Range#step</code> prohibits a negative step when a block is given.</p>
<pre><code>>> (6..3).step(-1) {|i| p i }
Traceback (most recent call last):
5: from /home/mrkn/.rbenv/versions/2.7/bin/irb:23:in `<main>'
4: from /home/mrkn/.rbenv/versions/2.7/bin/irb:23:in `load'
3: from /home/mrkn/.rbenv/versions/2.7.1/lib/ruby/gems/2.7.0/gems/irb-1.2.4/exe/irb:11:in `<top (required)>'
2: from (irb):1
1: from (irb):1:in `step'
ArgumentError (step can't be negative)
</code></pre>
<p>But <code>Range#step</code> allows a negative step when it is called without a block. In this case, <code>Range#step</code> creates an ArithmeticSequence, and <code>ArithmeticSequence#each</code> can iterate with a negative step.</p>
<pre><code>>> (6..3).step(-1).each {|i| p i }
6
5
4
3
=> ((6..3).step(-1))
</code></pre>
<p>I think the prohibition of a negative step in <code>Range#step</code> has already been meaningless, so it may be better to permit it for consistency.</p> Ruby master - Feature #17184 (Open): No stdlib function to perform simple string replacementhttps://bugs.ruby-lang.org/issues/171842020-09-24T11:37:04Zsheerun (Adam Stankiewicz)sheerun@sher.pl
<p>I have following simple <code>build.rb</code>:</p>
<pre><code class="rb syntaxhl" data-language="rb"><span class="n">template</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s1">'template.vim'</span><span class="p">)</span>
<span class="n">script</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s1">'script.vim'</span><span class="p">)</span>
<span class="no">File</span><span class="p">.</span><span class="nf">write</span><span class="p">(</span><span class="s1">'app.vim'</span><span class="p">,</span> <span class="n">template</span><span class="p">.</span><span class="nf">gsub</span><span class="p">(</span><span class="s2">"SCRIPT"</span><span class="p">,</span> <span class="n">script</span><span class="p">))</span>
</code></pre>
<p>And then following <code>template.vim</code>:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
SCRIPT
</code></pre>
<p>Plus following <code>script.vim</code>:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s\+"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>I'd expect that the script above produces <code>app.vim</code> with following contents:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
<span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s\+"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>Unfortunately it produces following:</p>
<pre><code class="vim syntaxhl" data-language="vim"><span class="c">" some header</span>
<span class="k">if</span> <span class="nv">g:something</span> <span class="p">=~</span> <span class="s2">"\s"</span>
echo <span class="s1">'g:something is empty'</span>
<span class="k">endif</span>
</code></pre>
<p>It's probably because gsub interprets <code>\+</code> in script as back-reference.</p>
<p>I tried to find replacement function in ruby that just replaces one string with something else, without interpreting replacement in any way, but surprisingly I haven't found any.. Am I mistaken?</p> Ruby master - Feature #16992 (Open): Sets: officially orderedhttps://bugs.ruby-lang.org/issues/169922020-06-26T20:30:50Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>Officially, set elements have uncertain order. This predades when Hash started being ordered (Ruby 1.9.0, Xmas 2007). Sets have since been de-facto insertion-ordered. FYI, in those 13 years, there have been about 70 commits to <code>lib/set.rb</code>.</p>
<p>I have the impression that a non-negligible amount of code in the wild rely on sets being ordered, at least under most circumstances. I feel that this should be officialized.</p>
<p>If sets are truly unordered, then why do we hesitate to make an optimization of <code>&</code> and <code>|</code>: <a href="https://bugs.ruby-lang.org/issues/15281" class="external">https://bugs.ruby-lang.org/issues/15281</a></p>
<p>See also: <a href="https://bugs.ruby-lang.org/issues/14069" class="external">https://bugs.ruby-lang.org/issues/14069</a></p> Ruby master - Feature #16986 (Open): Anonymous Struct literalhttps://bugs.ruby-lang.org/issues/169862020-06-26T06:58:53Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>How about introducing anonymous Struct literal such as <code>${a: 1, b: 2}</code>?<br>
It is almost the same as <code>Struct.new(:a, :b).new(1, 2)</code>.</p>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>In many cases, people use hash objects to represent a set of values such as <code>person = {name: "ko1", country: 'Japan'}</code> and access its values through <code>person[:name]</code> and so on. It is not easy to write (three characters <code>[:]</code>!), and it easily introduces misspelling (<code>person[:nama]</code> doesn't raise an error).</p>
<p>If we make a <code>Struct</code> object by doing <code>Person = Struct.new(:name, :age)</code> and <code>person = Person.new('ko1', 'Japan')</code>, we can access its values through <code>person.name</code> naturally. However, it costs coding. And in some cases, we don't want to name the class (such as <code>Person</code>).</p>
<p>Using <code>OpenStruct</code> (<code>person = OpenStruct.new(name: "ko1", country: "Japan")</code>), we can access it through <code>person.name</code>, but we can extend the fields unintentionally, and the performance is not good.</p>
<p>Of course, we can define a class <code>Person</code> with attr_readers. But it takes several lines.</p>
<p>To summarize the needs:</p>
<ul>
<li>Easy to write
<ul>
<li>Doesn't require declaring the class</li>
<li>Accessible through <code>person.name</code> format</li>
</ul>
</li>
<li>Limited fields</li>
<li>Better performance</li>
</ul>
<a name="Idea"></a>
<h2 >Idea<a href="#Idea" class="wiki-anchor">¶</a></h2>
<p>Introduce new literal syntax for an anonymous Struct such as: <code>${ a: 1, b: 2 }</code>.<br>
Similar to Hash syntax (with labels), but with <code>$</code> prefix to distinguish.</p>
<p>Anonymous structs which have the same member in the same order share their class.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">s1</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">}</span>
<span class="n">s2</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">}</span>
<span class="n">assert</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s2</span>
<span class="n">s3</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">,</span> <span class="ss">c: </span><span class="mi">3</span><span class="p">,</span> <span class="ss">b: </span><span class="mi">2</span><span class="p">}</span>
<span class="n">s4</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="ss">d: </span><span class="mi">4</span><span class="p">}</span>
<span class="n">assert_equal</span> <span class="kp">false</span><span class="p">,</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s3</span>
<span class="n">assert_equal</span> <span class="kp">false</span><span class="p">,</span> <span class="n">s1</span> <span class="o">==</span> <span class="n">s4</span>
</code></pre>
<a name="Note"></a>
<h2 >Note<a href="#Note" class="wiki-anchor">¶</a></h2>
<p>Unlike Hash literal syntax, this proposal only allows <code>label: expr</code> notation. No <code>${**h}</code> syntax.<br>
This is because if we allow to splat a Hash, it can be a vulnerability by splatting outer-input Hash.</p>
<p>Thanks to this spec, we can specify anonymous Struct classes at compile time.<br>
We don't need to find or create Struct classes at runtime.</p>
<a name="Implementatation"></a>
<h2 >Implementatation<a href="#Implementatation" class="wiki-anchor">¶</a></h2>
<p><a href="https://github.com/ruby/ruby/pull/3259" class="external">https://github.com/ruby/ruby/pull/3259</a></p>
<a name="Discussion"></a>
<h1 >Discussion<a href="#Discussion" class="wiki-anchor">¶</a></h1>
<a name="Notation"></a>
<h2 >Notation<a href="#Notation" class="wiki-anchor">¶</a></h2>
<p>Matz said he thought about <code>{|a: 1, b: 2 |}</code> syntax.</p>
<a name="Performance"></a>
<h2 >Performance<a href="#Performance" class="wiki-anchor">¶</a></h2>
<p>Surprisingly, Hash is fast and Struct is slow.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Benchmark</span><span class="p">.</span><span class="nf">driver</span> <span class="k">do</span> <span class="o">|</span><span class="n">r</span><span class="o">|</span>
<span class="n">r</span><span class="p">.</span><span class="nf">prelude</span> <span class="o"><<~</span><span class="no">PRELUDE</span><span class="sh">
st = Struct.new(:a, :b).new(1, 2)
hs = {a: 1, b: 2}
class C
attr_reader :a, :b
def initialize() = (@a = 1; @b = 2)
end
ob = C.new
</span><span class="no"> PRELUDE</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"ob.a"</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"hs[:a]"</span>
<span class="n">r</span><span class="p">.</span><span class="nf">report</span> <span class="s2">"st.a"</span>
<span class="k">end</span>
<span class="cp">__END__
Warming up --------------------------------------
ob.a 38.100M i/s - 38.142M times in 1.001101s (26.25ns/i, 76clocks/i)
hs[:a] 37.845M i/s - 38.037M times in 1.005051s (26.42ns/i, 76clocks/i)
st.a 33.348M i/s - 33.612M times in 1.007904s (29.99ns/i, 87clocks/i)
Calculating -------------------------------------
ob.a 87.917M i/s - 114.300M times in 1.300085s (11.37ns/i, 33clocks/i)
hs[:a] 85.504M i/s - 113.536M times in 1.327850s (11.70ns/i, 33clocks/i)
st.a 61.337M i/s - 100.045M times in 1.631064s (16.30ns/i, 47clocks/i)
Comparison:
ob.a: 87917391.4 i/s
hs[:a]: 85503703.6 i/s - 1.03x slower
st.a: 61337463.3 i/s - 1.43x slower
</span></code></pre>
<p>I believe we can speed up <code>Struct</code> similarly to ivar accesses, so we can improve the performance.</p>
<p>BTW, OpenStruct (os.a) is slow.</p>
<pre><code>Comparison:
hs[:a]: 92835317.7 i/s
ob.a: 85865849.5 i/s - 1.08x slower
st.a: 53480417.5 i/s - 1.74x slower
os.a: 12541267.7 i/s - 7.40x slower
</code></pre>
<p>For memory consumption, <code>Struct</code> is more lightweight because we don't need to keep the key names.</p>
<a name="Naming"></a>
<h2 >Naming<a href="#Naming" class="wiki-anchor">¶</a></h2>
<p>If we name an anonymous class, literals with the same members share the name.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">s1</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="n">a</span><span class="p">:</span><span class="mi">1</span><span class="p">}</span>
<span class="n">s2</span> <span class="o">=</span> <span class="err">$</span><span class="p">{</span><span class="n">a</span><span class="p">:</span><span class="mi">2</span><span class="p">}</span>
<span class="nb">p</span> <span class="p">[</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">]</span> <span class="c1">#=> [#<struct a=1>, #<struct a=2>]</span>
<span class="no">A</span> <span class="o">=</span> <span class="n">s1</span><span class="p">.</span><span class="nf">class</span>
<span class="nb">p</span> <span class="p">[</span><span class="n">s1</span><span class="p">,</span> <span class="n">s2</span><span class="p">]</span> <span class="c1">#=> [#<struct A a=1>, #<struct A a=2>]</span>
</code></pre>
<p>Maybe that is not a good behavior.</p> Ruby master - Feature #16894 (Open): Integer division for Ruby 3https://bugs.ruby-lang.org/issues/168942020-05-15T03:20:39Zankane (Andrew Kane)
<p>Hi Ruby team,</p>
<p>It'd be great if division in Ruby matched what we all learned in school.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="o">==</span> <span class="mf">0.5</span>
</code></pre>
<p>New developers wouldn't immediately be confused when they try to do division and experienced developers could stop adding to_f to their code (typically after they get tripped up on the first run). In my experience, floating point division is way more common than floor division. This could definitely break existing code, so I understand it's a decision that shouldn't be made lightly. Overall, Ruby is really intuitive, but this is one place where it's not.</p>
<p>It looks like this was considered for Ruby 2.0 as well as few years ago in <a class="issue tracker-2 status-6 priority-4 priority-default closed" title="Feature: Integer#/ の改訂 (Rejected)" href="https://bugs.ruby-lang.org/issues/5512">#5512</a>, so feel free to close if it's not something you'd like to reconsider right now.</p> Ruby master - Feature #16461 (Assigned): Proc#usinghttps://bugs.ruby-lang.org/issues/164612019-12-28T03:32:34Zshugo (Shugo Maeda)
<a name="Overview"></a>
<h2 >Overview<a href="#Overview" class="wiki-anchor">¶</a></h2>
<p>I propose Proc#using to support block-level refinements.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">IntegerDivExt</span>
<span class="n">refine</span> <span class="no">Integer</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">/</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="n">quo</span><span class="p">(</span><span class="n">other</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span> <span class="c1"># using IntegerDivExt in the block represented by the Proc object</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_eval</span><span class="p">(</span><span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="c1"># necessary where blocks are defined (not where Proc#using is called)</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_eval_with_integer_div_ext</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="PoC-implementation"></a>
<h2 >PoC implementation<a href="#PoC-implementation" class="wiki-anchor">¶</a></h2>
<p>For CRuby: <a href="https://github.com/shugo/ruby/pull/2" class="external">https://github.com/shugo/ruby/pull/2</a><br>
For JRuby: <a href="https://github.com/shugo/jruby/pull/1" class="external">https://github.com/shugo/jruby/pull/1</a></p>
<a name="Background"></a>
<h2 >Background<a href="#Background" class="wiki-anchor">¶</a></h2>
<p>I proposed <a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086: using: option for instance_eval etc.</a> before, but it has problems:</p>
<ul>
<li>Thread safety: The same block can be invoked with different refinements in multiple threads, so it's hard to implement method caching.</li>
<li>_exec family support: {instance,class,module}_exec cannot be supported.</li>
<li>Implicit use of refinements: every blocks can be used with refinements, so there was implementation difficulty in JRuby and it has usability issue in headius's opinion.</li>
</ul>
<a name="Solutions-in-this-proposal"></a>
<h2 >Solutions in this proposal<a href="#Solutions-in-this-proposal" class="wiki-anchor">¶</a></h2>
<a name="Thread-safety"></a>
<h3 >Thread safety<a href="#Thread-safety" class="wiki-anchor">¶</a></h3>
<p>Proc#using affects the block represented by the Proc object, neither the specific Proc object nor the specific block invocation.<br>
Method calls in a block are resolved with refinements which are used by Proc#using in the block at the time.<br>
Once all possible refinements are used in the block, there is no need to invalidate method cache anymore.</p>
<p>See <a href="https://github.com/shugo/ruby/pull/2/commits/1c922614ad7d1fb43b73e195348c81da7a4546ef" class="external">these tests</a> to understand how it works.<br>
Which refinements are used is depending on the order of Proc#using invocations until all Proc#using calls are finished, but eventually method calls in a block are resolved with the same refinements.</p>
<a name="-_exec-family-support"></a>
<h3 >* _exec family support<a href="#-_exec-family-support" class="wiki-anchor">¶</a></h3>
<p><a href="https://bugs.ruby-lang.org/issues/12086" class="external">Feature #12086</a> was an extension of _eval family, so it cannot be used with _exec family, but Proc#using is independent from _eval family, and can be used with _exec family:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">instance_exec_with_integer_div_ext</span><span class="p">(</span><span class="n">obj</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="n">block</span><span class="p">.</span><span class="nf">using</span><span class="p">(</span><span class="no">IntegerDivExt</span><span class="p">)</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">instance_exec</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">Proc</span><span class="o">::</span><span class="no">Refinements</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
<span class="n">instance_exec_with_integer_div_ext</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">other</span><span class="o">|</span>
<span class="nb">p</span> <span class="nb">self</span> <span class="o">/</span> <span class="n">other</span> <span class="c1">#=> (1/2)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="mi">1</span> <span class="o">/</span> <span class="mi">2</span> <span class="c1">#=> 0</span>
</code></pre>
<a name="Implicit-use-of-refinements"></a>
<h3 >Implicit use of refinements<a href="#Implicit-use-of-refinements" class="wiki-anchor">¶</a></h3>
<p>Proc#using can be used only if <code>using Proc::Refinements</code> is called in the scope of the block represented by the Proc object.<br>
Otherwise, a RuntimeError is raised.</p>
<p>There are two reasons:</p>
<ul>
<li>JRuby creates a special CallSite for refinements at compile-time only when <code>using</code> is called at the scope.</li>
<li>When reading programs, it may help understanding behavior. IMHO, it may be unnecessary if libraries which uses Proc#using are well documented.</li>
</ul>
<p><code>Proc::Refinements</code> is a dummy module, and has no actual refinements.</p> Ruby master - Feature #15991 (Open): Allow questionmarks in variable nameshttps://bugs.ruby-lang.org/issues/159912019-07-08T09:18:43Zaquaj (Jérémie Bonal)
<p>Hi,</p>
<p>I thought such an issue would've already been discussed but no number of searches allowed me to find a similar request. Feel free to close if I missed a previous refusal.</p>
<p>From time to time, especially when trying to clear up complex conditional logic, I find myself wishing I could add <code>?</code> to variable names, since I got used to it while naming methods.</p>
<p>For example, currently:</p>
<pre><code>if (node? && terminal?) || (halting && (value == halting))
# ...
end
</code></pre>
<p>becomes</p>
<pre><code>last_node = self.node? && self.terminal?
halt_on_node = halting && (value == halting)
if last_node || halt_on_node
# ...
end
</code></pre>
<p><code>halt_on_node</code> is clear enough, but <code>last_node</code> feels like it would contain a node, instead of expressing its actual purpose ("is the node the last one?").<br>
Right now a developer would have two options as I see them:<br>
1 - extract the conditional to a method <code>def last_node?</code> which can be a bit much if it's the only place this code is called.<br>
2 - rename the variable something like <code>is_last_node</code>, which feels a bit silly since we're in ruby and used to seeing <code>?</code>s for predicates.</p>
<p>Trying to assign to a questionmarked variable (<code>a? = true</code>) raises a <code>SyntaxError</code>. IMHO, it would make for more coherent design to allow it, just like we do in method names.</p>
<p>I was afraid that <code>variable?</code> would be already parsed as beginning a ternary expression (<code>variable?1:3</code>) but this isn't parsed either, the only thing it's used for is for method calls (<code>a?5 <==> a?(5)</code>), so this change wouldn't disrupt any current behavior, the expression would just be looked up like any other call instead of only looking up methods.</p>
<p>The only thing I can see with this is that it might raise the issue of allowing <code>!</code>s in variable names too, which I'm not sure makes a lot of sense (unlike <code>?</code> which denotes "booleanness", a trait shared by variables and methods alike, I can't see how a variable would be "dangerous").</p> Ruby master - Feature #15837 (Open): Module#name_componentshttps://bugs.ruby-lang.org/issues/158372019-05-08T03:49:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>I sometimes wrote the expression like below to extract the components of class path:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">klass</span><span class="p">.</span><span class="nf">name</span><span class="p">.</span><span class="nf">split</span><span class="p">(</span><span class="s1">'::'</span><span class="p">).</span><span class="nf">last</span>
</code></pre>
<p>Similar expressions can be found in ruby-trunk:</p>
<pre><code>mrkn@mrkn-devel:~/src/github.com/ruby/ruby$ git grep split..::
ext/json/lib/json/common.rb: path.to_s.split(/::/).inject(Object) do |p, c|
ext/openssl/lib/openssl/config.rb: refsec, ref = ref.split('::', 2)
ext/psych/lib/psych/visitors/yaml_tree.rb: method = "visit_#{(klass.name || '').split('::').join('_')}"
lib/bundler/cli/gem.rb: constant_array = constant_name.split("::")
lib/bundler/vendor/molinillo/lib/molinillo/errors.rb: solver_name = opts.delete(:solver_name) { self.class.name.split('::').first }
lib/bundler/vendor/thor/lib/thor/parser/argument.rb: class_name = self.class.name.split("::").last
lib/bundler/vendor/thor/lib/thor/parser/arguments.rb: class_name = self.class.name.split("::").last.downcase
lib/optparse/version.rb: pkg = pkg.split(/::|\//).inject(::Object) {|m, c| m.const_get(c)}
lib/optparse/version.rb: path.split(/::|\//).inject(base) do |klass, name|
lib/rdoc/any_method.rb: name = @full_name.split('::')
lib/rdoc/context.rb: names = ename.split('::')
lib/rdoc/context.rb: path = [prefix] + path.split('::')
lib/rdoc/method_attr.rb: $1.split('::').last. # ClassName => class_name
lib/rdoc/parser/c.rb: ([\w\. \t]+ = \s+)?rb_define_(class|module)_under[\t\w, (]*?"(#{class_name.split('::').last})"%xm then
lib/rdoc/parser/ruby.rb: obj = name_t[:text].split("::").inject(Object) do |state, item|
lib/rdoc/store.rb: name = klass_name.split('::').last
lib/rdoc/store.rb: File.join @path, *klass_name.split('::')
lib/rdoc/store.rb: method_name = method_name.split('::').last
lib/rss/atom.rb: "#{self.class.name.split(/::/).last.downcase}="
lib/rss/atom.rb: target.__send__(self.class.name.split(/::/).last.downcase) {|x| x}
lib/rss/atom.rb: target.__send__("new_#{self.class.name.split(/::/).last.downcase}")
lib/rss/rss.rb: tag_name = klass.name.split(/::/).last
spec/bundler/support/artifice/fail.rb: const = name.split("::").reduce(Object) {|mod, sym| mod.const_get(sym) }
spec/mspec/lib/mspec/utils/name_map.rb: c.split('::').inject(base) do |dir, name|
spec/mspec/lib/mspec/utils/name_map.rb: name = mapping[c.split('::').last] || mapping.fetch(:default)
</code></pre>
<p>I think we need <code>Module#name_components</code> method that returns the array of symbols (or string, I prefer symbols) which comes from splitting name by <code>::</code>.</p> Ruby master - Bug #15764 (Open): Whitespace and control characters should not be permitted in tokenshttps://bugs.ruby-lang.org/issues/157642019-04-11T20:59:47ZBatmanAoD (Kyle Strand)kyle.j.strand@gmail.com
<p>As of Ruby 2.5.1p57, it appears that all valid Unicode code-points above 128 are permitted in tokens. This includes whitespace and control characters.</p>
<p>This was demonstrated here: <a href="https://gist.github.com/qrohlf/7045823" class="external">https://gist.github.com/qrohlf/7045823</a></p>
<p>I have attached the raw download from the above gist.</p>
<p>The issue has been discussed on StackOverflow: <a href="https://stackoverflow.com/q/34455427/1858225" class="external">https://stackoverflow.com/q/34455427/1858225</a></p>
<p>I would say this is arguably a bug, but I am marking this ticket as a "feature" since the current behavior could be considered by-design.</p> Ruby master - Feature #15554 (Open): warn/error passing a block to a method which never use a blockhttps://bugs.ruby-lang.org/issues/155542019-01-22T04:48:10Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p>Warn or raise an ArgumentError if block is passed to a method which does not use a block.<br>
In other words, detect "block user methods" implicitly and only "block user methods" can accept a block.</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>Sometimes, we pass a block to a method which ignores the passed block accidentally.</p>
<pre><code>def my_open(name)
open(name)
end
# user hopes it works as Kernel#open which invokes a block with opened file.
my_open(name){|f| important_work_with f }
# but simply ignored...
</code></pre>
<p>To solve this issue, this feature request propose showing warnings or raising an exception on such case.</p>
<p>Last developer's meeting, matz proposed <code>&nil</code> which declares this method never receive a block. It is explicit, but it is tough to add this <code>&nil</code> parameter declaration to all of methods (do you want to add it to <code>def []=(i, e, &nil)</code>?).<br>
(I agree <code>&nil</code> is valuable on some situations)</p>
<a name="Spec"></a>
<h1 >Spec<a href="#Spec" class="wiki-anchor">¶</a></h1>
<a name="Define-use-a-block-methods"></a>
<h2 >Define "use a block" methods<a href="#Define-use-a-block-methods" class="wiki-anchor">¶</a></h2>
<p>We need to define which method accepts a block and which method does not.</p>
<ul>
<li>(1) method has a block parameter (<code>&b</code>)</li>
<li>(2) method body has `yield'</li>
<li>(3) method body has <code>super</code> (ZSUPER in internal terminology) or <code>super(...)</code>
</li>
<li>(4) method body has singleton method (optional)</li>
</ul>
<p>(1) and (2) is very clear. I need to explain about (3) and (4).</p>
<p>(3). <code>super</code> (ZSUPER) passes all parameters as arguments. So there is no surprise that which can accept <code>block</code>.<br>
However <code>super(...)</code> also passes a block if no explicit block passing (like <code>super(){}</code> or <code>super(&b)</code>) are written.<br>
I'm not sure we need to continue this strange specification, but to keep compatibility depending this spec, I add this rule.</p>
<p>(4). surprisingly, the following code invoke a block:</p>
<pre><code>def foo
class << Object.new
yield
end
end
foo{ p :ok } #=> :ok
</code></pre>
<p>I'm also not sure we need to keep this spec, but to allow this spec, I added (4) rule.<br>
Strictly speaking, it is not required, but we don't keep the link from singleton class ISeq to lexical parent iseq now, so I added it.</p>
<a name="Exceptional-cases"></a>
<h2 >Exceptional cases<a href="#Exceptional-cases" class="wiki-anchor">¶</a></h2>
<p>A method called by <code>super</code> doesn<code>t warn warning even if this method doesn't use a block. The rule (3) can pass blocks easily and there are many methods don</code>t use a block.</p>
<p>So my patch ignores callings by <code>super</code>.</p>
<a name="corner-cases"></a>
<h2 >corner cases<a href="#corner-cases" class="wiki-anchor">¶</a></h2>
<p>There are several cases to use block without (1)-(4) rules.</p>
<h3>
<code>Proc.new/proc/lambda</code> without a block</h3>
<p>Now it was deprecated in r66772 (<a class="changeset" title="proc.c: proc without block * proc.c (proc_new): promoted lambda/proc/Proc.new with no block in..." href="https://bugs.ruby-lang.org/projects/ruby-master/repository/git/revisions/9f1fb0a17febc59356d58cef5e98db61a3c03550">9f1fb0a17febc59356d58cef5e98db61a3c03550</a>).<br>
Related discussion: [Bug <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Proc.new with no block shouldn't always warn (Rejected)" href="https://bugs.ruby-lang.org/issues/15539">#15539</a>]</p>
<a name="block_given"></a>
<h3 ><code>block_given?</code><a href="#block_given" class="wiki-anchor">¶</a></h3>
<p><code>block_given?</code> expects block, but I believe we use it with <code>yield</code> or a block parameter.<br>
If you know the usecase without them, please tell us.</p>
<h3>
<code>yield</code> in <code>eval</code>
</h3>
<p>We can't know <code>yield</code> (or (3), (4) rule) in an <code>eval</code> evaluating string at calling time.</p>
<pre><code>def foo
eval('yield`)
end
foo{} # at calling time,
# we can't know the method foo can accept a block or not.
</code></pre>
<p>So I added a warning to use <code>yield</code> in <code>eval</code> like that: <code>test.rb:4: warning: use yield in eval will not be supported in Ruby 3.</code></p>
<p>Workaround is use a block parameter explicitly.</p>
<pre><code>def foo &b
eval('b.call')
end
foo{ p :ok }
</code></pre>
<a name="Implementation"></a>
<h1 >Implementation<a href="#Implementation" class="wiki-anchor">¶</a></h1>
<p>Strategy is:</p>
<ul>
<li>[compile time] introduce <code>iseq::has_yield</code> field and check it if the iseq (or child iseq) contains <code>yield</code> (or something)</li>
<li>[calling time] if block is given, check <code>iseq::has_yield</code> flag and show warning (or raise an exception)</li>
</ul>
<p><a href="https://gist.github.com/ko1/c9148ad0224bf5befa3cc76ed2220c0b" class="external">https://gist.github.com/ko1/c9148ad0224bf5befa3cc76ed2220c0b</a></p>
<p>On this patch, now it raises an error to make it easy to detect.<br>
It is easy to switch to show the warning.</p>
<a name="Evaluation-and-discussion"></a>
<h1 >Evaluation and discussion<a href="#Evaluation-and-discussion" class="wiki-anchor">¶</a></h1>
<p>I tried to avoid ruby's tests.</p>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786</a></p>
<p>Here is a patch.</p>
<p>There are several patterns to avoid warnings.</p>
<a name="tests-for-block_given-Procnew-and-similar-without-block"></a>
<h2 >tests for <code>block_given?</code>, <code>Proc.new</code> (and similar) without block<a href="#tests-for-block_given-Procnew-and-similar-without-block" class="wiki-anchor">¶</a></h2>
<p>Add a dummy block parameter.<br>
It is test-specific issue.</p>
<h2>empty <code>each</code>
</h2>
<p>Some tests add <code>each</code> methods do not <code>yield</code>, like: <code>def each; end</code>.<br>
Maybe test-specific issue, and adding a dummy block parameter.</p>
<a name="Subtyping-duck-typing"></a>
<h2 >Subtyping / duck typing<a href="#Subtyping-duck-typing" class="wiki-anchor">¶</a></h2>
<p><a href="https://github.com/ruby/ruby/blob/c01a5ee85e2d6a7128cccafb143bfa694284ca87/lib/optparse.rb#L698" class="external">https://github.com/ruby/ruby/blob/c01a5ee85e2d6a7128cccafb143bfa694284ca87/lib/optparse.rb#L698</a></p>
<p>This <code>parse</code> method doesn't use <code>yield</code>, but other sub-type's <code>parse</code> methods use.</p>
<h2>
<code>super</code> with <code>new</code> method</h2>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L61" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L61</a></p>
<p>This method override <code>Class#new</code> method and introduce a hook with block (yield a block in this hook code).</p>
<p><a href="https://github.com/ruby/ruby/blob/trunk/lib/rubygems/package/tar_writer.rb#L81" class="external">https://github.com/ruby/ruby/blob/trunk/lib/rubygems/package/tar_writer.rb#L81</a></p>
<p>In this method, call <code>super</code> and it also passing a block. However, called <code>initialize</code> doesn't use a block.</p>
<a name="Change-robustness"></a>
<h2 >Change robustness<a href="#Change-robustness" class="wiki-anchor">¶</a></h2>
<p>This change reduce robustness for API change.</p>
<p><code>Delegator</code> requires to support <code>__getobj__</code> for client classes.<br>
Now <code>__getobj__</code> should accept block but most of <code>__getobj__</code> clients do not call given block.</p>
<p><a href="https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L80" class="external">https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L80</a></p>
<p>This is because of delegator.rb's API change.</p>
<p><a href="https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L86" class="external">https://gist.github.com/ko1/37483e7940cdc4390bf8eb0001883786#file-tests-patch-L86</a></p>
<p>Nobu says calling block is not required (ignoring a block is no problem) so it is not a bug for delegator client classes.</p>
<a name="Found-issues"></a>
<h2 >Found issues.<a href="#Found-issues" class="wiki-anchor">¶</a></h2>
<pre><code>[ 2945/20449] Rinda::TestRingServer#test_do_reply = 0.00 s
1) Error:
Rinda::TestRingServer#test_do_reply:
ArgumentError: passing block to the method "with_timeout" (defined at /home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:787) is never used.
/home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:635:in `test_do_reply'
[ 2946/20449] Rinda::TestRingServer#test_do_reply_local = 0.00 s
2) Error:
Rinda::TestRingServer#test_do_reply_local:
ArgumentError: passing block to the method "with_timeout" (defined at /home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:787) is never used.
/home/ko1/src/ruby/trunk/test/rinda/test_rinda.rb:657:in `test_do_reply_local'
[10024/20449] TestGemRequestSetGemDependencyAPI#test_platform_mswin = 0.01 s
3) Error:
TestGemRequestSetGemDependencyAPI#test_platform_mswin:
ArgumentError: passing block to the method "util_set_arch" (defined at /home/ko1/src/ruby/trunk/lib/rubygems/test_case.rb:1053) is never used.
/home/ko1/src/ruby/trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb:655:in `test_platform_mswin'
[10025/20449] TestGemRequestSetGemDependencyAPI#test_platforms = 0.01 s
4) Error:
TestGemRequestSetGemDependencyAPI#test_platforms:
ArgumentError: passing block to the method "util_set_arch" (defined at /home/ko1/src/ruby/trunk/lib/rubygems/test_case.rb:1053) is never used.
/home/ko1/src/ruby/trunk/test/rubygems/test_gem_request_set_gem_dependency_api.rb:711:in `test_platforms'
</code></pre>
<p>These 4 detection show the problem. <code>with_timeout</code> method (used in Rinda test) and <code>util_set_arch</code> method (used in Rubygems test) simply ignore the given block.<br>
So these tests are simply ignored.</p>
<p>I reported them. (<a href="https://github.com/rubygems/rubygems/issues/2601" class="external">https://github.com/rubygems/rubygems/issues/2601</a>)</p>
<a name="raise-an-error-or-show-a-warning"></a>
<h2 >raise an error or show a warning?<a href="#raise-an-error-or-show-a-warning" class="wiki-anchor">¶</a></h2>
<p>At least, Ruby 2.7 should show warning for this kind of violation with <code>-w</code>.<br>
How about for Ruby3?</p> Ruby master - Feature #15445 (Open): Reject '.123' in Float() methodhttps://bugs.ruby-lang.org/issues/154452018-12-21T00:16:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>Since ruby 1.8, Ruby occurs a syntax error for "." floating literal.<br>
But Float() method accepts such form now.</p>
<p>I propose to reject "." form even in Float() method.</p> Ruby master - Feature #15330 (Open): autoload_relativehttps://bugs.ruby-lang.org/issues/153302018-11-21T23:43:41Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>I'd like to propose a way to autoload a constant using a relative path.</p>
<p>It could look like:</p>
<pre><code>autoload_relative :MyConst, 'models/my_const'
</code></pre>
<p>My proposal raises two questions:</p>
<ol>
<li>what's the future of <code>autoload</code>?</li>
</ol>
<p>I believe that <code>autoload</code> has been there for years, it is used successfully and has no real alternative.</p>
<p>I looked at a sample of 430 top gems (took the 500 top ranked according to Libraries.io, removed those that I failed to process). The number of those gems that appear to use <code>autoload</code> at least once is 94 of those (22%).</p>
<p>The number of lines in the code where <code>autoload</code> is called can be quite big. The top 5 are:<br>
vagrant: 235<br>
yard: 206<br>
ffaker: 155<br>
aws-sdk: 152<br>
rdoc: 92</p>
<p>This is a minimum bound, as some gems might be using loops, my processing would only detect the one place in the code with <code>autoload</code>.</p>
<ol start="2">
<li>are many autoladed paths relative?</li>
</ol>
<p>My preliminary numbers indicate that of the 94 gems using autoload, at least 75 are autoloading some relative files. That's a lower bound, as my algorithm is pretty crude and will only count the simplest cases as being relative. An example of gem my algorithm does not detect is <code>yard</code>, because the author wrote a small method to map the relative paths to global paths (code here: <a href="https://github.com/lsegal/yard/blob/master/lib/yard/autoload.rb#L3" class="external">https://github.com/lsegal/yard/blob/master/lib/yard/autoload.rb#L3</a> )</p>
<p>Of those where my processing detects the relative requires, a vast majority are relative. The average is that 94% of autoloaded files are relative and would benefit from <code>require_relative</code></p>
<p>In summary: I am convinced that <code>autoload</code> should remain in Ruby indefinitely. <code>autoload_relative</code> would actually be more useful than <code>autoload</code>. Even if the future of <code>autoload</code> remains uncertain, I would recommend adding <code>autoload_relative</code>; if it is ever decided to actually remove <code>autoload</code>, removing <code>autoload_relative</code> would not really add to the (huge) burden of gem maintainers.</p> Ruby master - Feature #15277 (Open): at_exechttps://bugs.ruby-lang.org/issues/152772018-11-02T19:23:47Zmarcandre (Marc-Andre Lafortune)marcandre-ruby-core@marc-andre.ca
<p>There's currently no easy way to have code executed before a subsequent call to <code>exec</code>. One has to monkey-patch the builtin method.</p>
<p>I'd like to propose a new method <code>at_exec</code> that would be very similar to <code>at_exit</code>, except that the callbacks are triggered before the current process is replaced by the external command.</p>
<pre><code># This would output "Hello", "Bye", and "Foo"
at_exec { puts "Bye!" }
puts "Hello"
exec "echo Foo"
</code></pre>
<p>Use case: we roll our own in <code>DeepCover</code>. Some test suites will call <code>exec</code>, and we need to store our counters before that happens.</p> Ruby master - Feature #15192 (Open): Introduce a new "shortcut assigning" syntax to convenient se...https://bugs.ruby-lang.org/issues/151922018-10-02T04:54:28Zjjyr (Jinyang Jiang)jjyruby@gmail.com
<p>Motivation:</p>
<p>Introduce a new syntax for convenient setup instance variables for objects.</p>
<p>The problem:</p>
<p>Currently, setup instance variables in Ruby is too verbose.<br>
Basically, we need to write the meaningless assigning code again and again to assign variables</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Person</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="nb">name</span><span class="p">:,</span> <span class="n">age</span><span class="p">:,</span> <span class="n">gender</span><span class="p">:,</span> <span class="n">country</span><span class="p">:)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
<span class="vi">@gender</span> <span class="o">=</span> <span class="n">gender</span>
<span class="vi">@country</span> <span class="o">=</span> <span class="n">country</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># we can use Struct to avoiding this</span>
<span class="no">Person</span> <span class="o">=</span> <span class="no">Struct</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">:name</span><span class="p">,</span> <span class="ss">:age</span><span class="p">,</span> <span class="ss">:gender</span><span class="p">,</span> <span class="ss">:country</span><span class="p">,</span> <span class="ss">keyword_init: </span><span class="kp">true</span><span class="p">)</span>
<span class="c1"># let's see a real-world case, which can't use Struct to describe an initializing process, from https://github.com/ciri-ethereum/ciri/blob/748985ccf7a620a2e480706a5a6b38f56409d487/lib/ciri/devp2p/server.rb#L54</span>
<span class="c1"># Because we want to do something more than just assigning instance variables</span>
<span class="k">class</span> <span class="nc">Server</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">private_key</span><span class="p">:,</span> <span class="n">protocol_manage</span><span class="p">:,</span> <span class="ss">bootstrap_nodes: </span><span class="p">[],</span>
<span class="ss">node_name: </span><span class="s1">'Ciri'</span><span class="p">,</span> <span class="ss">tcp_host: </span><span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="ss">tcp_port: </span><span class="mi">33033</span><span class="p">)</span>
<span class="vi">@private_key</span> <span class="o">=</span> <span class="n">private_key</span>
<span class="vi">@node_name</span> <span class="o">=</span> <span class="n">node_name</span>
<span class="vi">@bootstrap_nodes</span> <span class="o">=</span> <span class="n">bootstrap_nodes</span>
<span class="vi">@protocol_manage</span> <span class="o">=</span> <span class="n">protocol_manage</span>
<span class="n">server_node_id</span> <span class="o">=</span> <span class="no">NodeID</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">)</span>
<span class="n">caps</span> <span class="o">=</span> <span class="p">[</span><span class="no">Cap</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s1">'eth'</span><span class="p">,</span> <span class="ss">version: </span><span class="mi">63</span><span class="p">)]</span>
<span class="vi">@handshake</span> <span class="o">=</span> <span class="no">ProtocolHandshake</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">version: </span><span class="no">BASE_PROTOCOL_VERSION</span><span class="p">,</span> <span class="ss">name: </span><span class="vi">@node_name</span><span class="p">,</span> <span class="ss">id: </span><span class="n">server_node_id</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="ss">caps: </span><span class="n">caps</span><span class="p">)</span>
<span class="vi">@tcp_host</span> <span class="o">=</span> <span class="n">tcp_host</span>
<span class="vi">@tcp_port</span> <span class="o">=</span> <span class="n">tcp_port</span>
<span class="vi">@dial</span> <span class="o">=</span> <span class="no">Dial</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">bootstrap_nodes: </span><span class="n">bootstrap_nodes</span><span class="p">,</span> <span class="ss">private_key: </span><span class="n">private_key</span><span class="p">,</span> <span class="ss">handshake: </span><span class="vi">@handshake</span><span class="p">)</span>
<span class="vi">@network_state</span> <span class="o">=</span> <span class="no">NetworkState</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">protocol_manage</span><span class="p">)</span>
<span class="vi">@dial_scheduler</span> <span class="o">=</span> <span class="no">DialScheduler</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@network_state</span><span class="p">,</span> <span class="vi">@dial</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># Introduce a new "shortcut assigning" syntax for convenient setup</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="c1"># use @ prefix to describe instance variables.</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="vi">@name</span><span class="p">:,</span> <span class="vi">@age</span><span class="p">:,</span> <span class="vi">@gender</span><span class="p">:,</span> <span class="vi">@country</span><span class="p">:)</span>
<span class="k">end</span>
<span class="c1"># equal to</span>
<span class="k">def</span> <span class="nf">initialize2</span><span class="p">(</span><span class="nb">name</span><span class="p">:,</span> <span class="n">age</span><span class="p">:,</span> <span class="n">gender</span><span class="p">:,</span> <span class="n">country</span><span class="p">:)</span>
<span class="vi">@name</span> <span class="o">=</span> <span class="nb">name</span>
<span class="vi">@age</span> <span class="o">=</span> <span class="n">age</span>
<span class="vi">@gender</span> <span class="o">=</span> <span class="n">gender</span>
<span class="vi">@country</span> <span class="o">=</span> <span class="n">country</span>
<span class="k">end</span>
<span class="c1"># it should also work on position style arguments</span>
<span class="k">def</span> <span class="nf">initialize2</span><span class="p">(</span><span class="vi">@name</span><span class="p">,</span> <span class="vi">@age</span><span class="p">,</span> <span class="vi">@gender</span><span class="p">,</span> <span class="vi">@country</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># Our real-world case can be rewritten as below</span>
<span class="k">class</span> <span class="nc">Server</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">:,</span> <span class="vi">@protocol_manage</span><span class="p">:,</span> <span class="vi">@bootstrap_nodes</span><span class="p">:</span> <span class="p">[],</span>
<span class="vi">@node_name</span><span class="p">:</span> <span class="s1">'Ciri'</span><span class="p">,</span> <span class="vi">@tcp_host</span><span class="p">:</span> <span class="s1">'127.0.0.1'</span><span class="p">,</span> <span class="vi">@tcp_port</span><span class="p">:</span> <span class="mi">33033</span><span class="p">)</span>
<span class="n">server_node_id</span> <span class="o">=</span> <span class="no">NodeID</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@private_key</span><span class="p">)</span>
<span class="n">caps</span> <span class="o">=</span> <span class="p">[</span><span class="no">Cap</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">name: </span><span class="s1">'eth'</span><span class="p">,</span> <span class="ss">version: </span><span class="mi">63</span><span class="p">)]</span>
<span class="vi">@handshake</span> <span class="o">=</span> <span class="no">ProtocolHandshake</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">version: </span><span class="no">BASE_PROTOCOL_VERSION</span><span class="p">,</span> <span class="ss">name: </span><span class="vi">@node_name</span><span class="p">,</span> <span class="ss">id: </span><span class="n">server_node_id</span><span class="p">.</span><span class="nf">id</span><span class="p">,</span> <span class="ss">caps: </span><span class="n">caps</span><span class="p">)</span>
<span class="vi">@dial</span> <span class="o">=</span> <span class="no">Dial</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="ss">bootstrap_nodes: </span><span class="vi">@bootstrap_nodes</span><span class="p">,</span> <span class="ss">private_key: </span><span class="vi">@private_key</span><span class="p">,</span> <span class="ss">handshake: </span><span class="vi">@handshake</span><span class="p">)</span>
<span class="vi">@network_state</span> <span class="o">=</span> <span class="no">NetworkState</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@protocol_manage</span><span class="p">)</span>
<span class="vi">@dial_scheduler</span> <span class="o">=</span> <span class="no">DialScheduler</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vi">@network_state</span><span class="p">,</span> <span class="vi">@dial</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># consider to keep consistency, this "shortcut assigning" syntax should work for non-initialize methods</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="vi">@still_works</span><span class="p">)</span>
<span class="nb">p</span> <span class="vi">@still_works</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #15112 (Open): Introducing the short form of `STDERR.puts expr.inspect`.https://bugs.ruby-lang.org/issues/151122018-09-13T06:15:38Zmrkn (Kenta Murata)muraken@gmail.com
<p>I sometimes write <code>STDERR.puts obj.inspect</code> to print debug message to standard error.<br>
I want to write it as <code>STDERR.p obj</code>.<br>
It can be realized by introducing <code>p</code> singleton method in <code>STDERR</code> object.</p> Ruby master - Feature #14982 (Open): Improve namespace system in ruby to avoiding top-level name...https://bugs.ruby-lang.org/issues/149822018-08-11T04:26:06Zjjyr (Jinyang Jiang)jjyruby@gmail.com
<p>Updated: <a href="https://bugs.ruby-lang.org/issues/14982#note-5" class="external">https://bugs.ruby-lang.org/issues/14982#note-5</a></p>
<a name="Why"></a>
<h2 >Why<a href="#Why" class="wiki-anchor">¶</a></h2>
<p>Ruby has evaluation all class/module names in top-level context(aka TOPLEVEL_BINDING).<br>
As a user we basically hard to know how many names in the current context, is causing chaos in some cases. For example:</p>
<p>case 1:</p>
<p>Put common used errors class in a single file, like below</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># utils/errors.rb</span>
<span class="k">class</span> <span class="nc">FooError</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">BarError</span>
<span class="k">end</span>
</code></pre>
<p>In other files under 'utils' we want to use those errors, so the best practice is to use <code>require_relative 'errors'</code> in each file we need.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># utils/binary_helper.rb</span>
<span class="c1"># we forget require errors</span>
<span class="k">module</span> <span class="nn">BinaryHelper</span>
<span class="c1"># ...</span>
<span class="k">raise</span> <span class="no">BarError</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</code></pre>
<p>But sometime we may forget to require dependencies in a file, it's hard to notice because<br>
if RubyVM already execute the requires we still can access the name BarError,</p>
<p>but if user directly to require 'utils/binary_helper', he/she will got an NameError.</p>
<p>case 2:</p>
<p>Two gems use same top-level module name, so we can't use them together</p>
<a name="The-Reason-of-The-Problem"></a>
<h2 >The Reason of The Problem<a href="#The-Reason-of-The-Problem" class="wiki-anchor">¶</a></h2>
<p>The reason is we let module author to decision which module user can use. ('require' is basically evaluation, highly dependent on the module author's design)</p>
<p>But we should let users control which names to use and available in context. As many other popular languages dose(Rust, Python..)</p>
<p>I think the solution is basically the same philosophy compares to refinement feature.</p>
<a name="The-Design"></a>
<h2 >The Design<a href="#The-Design" class="wiki-anchor">¶</a></h2>
<p>I propose an improved namespace to Ruby, to solve the problems and still compatible with the current Ruby module system.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="k">end</span>
<span class="c1"># introduce Kernel#namespace</span>
<span class="n">namespace</span> <span class="ss">:Hello</span> <span class="k">do</span>
<span class="c1"># avoiding namespace chaos</span>
<span class="c1"># Foo -> NameError, can't access TOPLEVEL_BINDING directly</span>
<span class="c1"># Kernel#import method, introduce Foo name from TOPLEVEL_BINDING</span>
<span class="n">import</span> <span class="ss">:Foo</span>
<span class="c1"># in a namespace user can only access imported name</span>
<span class="no">Foo</span>
<span class="c1"># import constant to another alias name</span>
<span class="c1"># can avoid writing nested module/class names</span>
<span class="n">import</span> <span class="ss">:"A::B::C::D"</span><span class="p">,</span> <span class="ss">as: :E</span>
<span class="c1"># require then import, for convenient </span>
<span class="n">import</span> <span class="ss">:"A::B::C::D"</span><span class="p">,</span> <span class="ss">as: :E</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="c1"># import same name from two gems</span>
<span class="n">import</span> <span class="ss">:"Foo"</span><span class="p">,</span> <span class="ss">as: :Foo_A</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'foo_a'</span>
<span class="n">import</span> <span class="ss">:"Foo"</span><span class="p">,</span> <span class="ss">as: :Foo_B</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'foo_b'</span>
<span class="c1"># import names in batch</span>
<span class="n">import</span> <span class="sx">%i{"A::B::C::D", "AnotherClass"}</span><span class="p">,</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="c1"># import and alias in batch</span>
<span class="n">import</span> <span class="p">{</span><span class="ss">:"A::B::C::D"</span> <span class="o">=></span> <span class="ss">:E</span><span class="p">,</span> <span class="ss">:Foo</span> <span class="o">=></span> <span class="no">Foo2</span><span class="p">},</span> <span class="ss">from: </span><span class="s1">'some_rb_file'</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="k">def</span> <span class="nf">xxx</span>
<span class="c1"># can access all names in namespace scope</span>
<span class="p">[</span><span class="no">Foo</span><span class="p">,</span> <span class="no">Foo_A</span><span class="p">,</span> <span class="no">Foo_B</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Hello</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># -> module. namespace is just a module</span>
<span class="no">Hello</span><span class="o">::</span><span class="no">Bar</span> <span class="c1"># so we do not broken current ruby module design</span>
<span class="c1"># namespace system is intent to let user to control names in context</span>
<span class="c1"># So user can choose use the old require way</span>
<span class="nb">require</span> <span class="s1">'hello'</span>
<span class="no">Hello</span><span class="o">::</span><span class="no">Bar</span>
<span class="c1"># Or user can use namespace system as we do in hello.rb</span>
<span class="n">namespace</span> <span class="ss">:Example</span> <span class="k">do</span>
<span class="n">import</span> <span class="ss">:"Hello::Bar"</span><span class="p">,</span> <span class="ss">as: :Bar</span>
<span class="no">Bar</span> <span class="c1"># ok</span>
<span class="no">Foo</span> <span class="c1"># name error, cause we do not import Foo in :Example namespace</span>
<span class="k">end</span>
<span class="no">Foo</span> <span class="c1"># ok, cause Foo is loaded in TOPLEVEL_BINDING</span>
<span class="c1"># define nested namespace</span>
<span class="c1"># more clear syntax than “module Example::NestedExample”</span>
<span class="n">namespace</span> <span class="ss">:NestedExample</span><span class="p">,</span> <span class="ss">under: </span><span class="no">Example</span> <span class="k">do</span>
<span class="k">end</span>
<span class="n">namespace</span> <span class="ss">:Example2</span> <span class="k">do</span>
<span class="n">namespace</span> <span class="ss">:NestedExample</span> <span class="k">do</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>Pros:</p>
<ul>
<li>Completely compatible with the current module system, a gem user can completely ignore whether a gem is write in Namespace or not.</li>
<li>User can completely control which names in current context/scope.</li>
<li>May solve the top module name conflict issue(depends on VM implementation).</li>
<li>Avoid introducing new keyword and syntax.</li>
<li>Type hint or name hint can be more accuracy under namespace(not sure).</li>
</ul>
<p>Cons:</p>
<ul>
<li>Need to modify Ruby VM to support the feature.</li>
</ul> Ruby master - Feature #14927 (Open): Loading multiple files at oncehttps://bugs.ruby-lang.org/issues/149272018-07-20T18:13:55ZAnonymous
<p>Just a proof concept I wanted to share. Maybe it could be useful?</p>
<p>Say you want to load all the .rb files in your lib directory:</p>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="no">Dir</span><span class="p">[</span><span class="s1">'lib/**/*.rb'</span><span class="p">].</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">file</span><span class="o">|</span> <span class="nb">load</span><span class="p">(</span><span class="n">file</span><span class="p">)</span> <span class="p">}</span>
</code></pre>
<p>This approach may not work if your files have dependencies like that:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># lib/foo.rb</span>
<span class="k">class</span> <span class="nc">Foo</span> <span class="o"><</span> <span class="no">Bar</span>
<span class="k">end</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># lib/bar.rb</span>
<span class="k">class</span> <span class="nc">Bar</span>
<span class="k">end</span>
</code></pre>
<p>Foo class needs Bar class. You will get a NameError (uninitialized constant Bar).</p>
<p>So in my personal projects, I use this algorithm to load all my files and to automatically take care of dependencies (class/include):</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">boot</span><span class="p">(</span><span class="n">files</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">while</span> <span class="n">i</span> <span class="o"><</span> <span class="n">files</span><span class="p">.</span><span class="nf">length</span>
<span class="k">begin</span>
<span class="nb">load</span><span class="p">(</span><span class="n">files</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
<span class="k">rescue</span> <span class="no">NameError</span>
<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
<span class="k">else</span>
<span class="k">while</span> <span class="n">i</span> <span class="o">></span> <span class="mi">0</span>
<span class="n">files</span><span class="p">.</span><span class="nf">push</span><span class="p">(</span><span class="n">files</span><span class="p">.</span><span class="nf">shift</span><span class="p">)</span>
<span class="n">i</span> <span class="o">-=</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="n">files</span><span class="p">.</span><span class="nf">shift</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="n">boot</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'lib/**/*.rb'</span><span class="p">]</span> <span class="c1"># It works! foo.rb and bar.rb are properly loaded.</span>
</code></pre>
<p>My point is: it would be cool if Kernel#load could receive an array of filenames (to load all these files in the proper order). So we could load all our libs with just a single line:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">load</span> <span class="no">Dir</span><span class="p">[</span><span class="s1">'{path1,path2}/**/*.rb'</span><span class="p">]</span>
</code></pre> Ruby master - Feature #14724 (Open): chains of inequalitieshttps://bugs.ruby-lang.org/issues/147242018-04-30T06:36:57Zgotoken (Kentaro Goto)gotoken@gmail.com
<p>In mathematics, chain of inequations is a shorthand notation for the conjunction of several inequations involving common expressions.</p>
<p>For example, <code>a < b <= c</code> for <code>a < b && b <= c</code></p>
<p>Chain notation makes code clearer, in particular, long common expression cases will be so. E.g.,</p>
<pre><code>cur.to_i - 2 <= timeval.tv_sec <= cur.to_i
</code></pre>
<p>is easier to read than</p>
<pre><code>cur.to_i - 2 <= timeval.tv_sec && timeval.tv_sec <= cur.to_i
</code></pre>
<p>because in the latter case we have to verify whether <code>timeval.tv_sec</code> is common or not by eyes.</p>
<p>Current syntax allows but redefining builtin methods are considered not practical. So here I request as a new syntax for the chains.</p>
<a name="Use-cases-applicable-conjunctions"></a>
<h3 >Use cases (applicable conjunctions)<a href="#Use-cases-applicable-conjunctions" class="wiki-anchor">¶</a></h3>
<p>lib/matrix.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">unless</span> <span class="mi">0</span> <span class="o"><=</span> <span class="n">column</span> <span class="o">&&</span> <span class="n">column</span> <span class="o"><</span> <span class="n">column_count</span>
</code></pre>
<p>lib/time.rb documents:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="c1"># block. For example:</span>
<span class="c1">#</span>
<span class="c1"># Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}</span>
</code></pre>
<p>spec/ruby/optional/capi/bignum_spec.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">raise</span> <span class="s2">"Bignum#coerce returned Fixnum"</span> <span class="k">if</span> <span class="n">fixnum_min</span> <span class="o"><=</span> <span class="n">n</span> <span class="o">&&</span> <span class="n">n</span> <span class="o"><=</span> <span class="n">fixnum_max</span>
</code></pre>
<p>test/fiddle/test_import.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="n">assert</span><span class="p">(</span><span class="n">cur</span><span class="p">.</span><span class="nf">to_i</span> <span class="o">-</span> <span class="mi">2</span> <span class="o"><=</span> <span class="n">timeval</span><span class="p">.</span><span class="nf">tv_sec</span> <span class="o">&&</span> <span class="n">timeval</span><span class="p">.</span><span class="nf">tv_sec</span> <span class="o"><=</span> <span class="n">cur</span><span class="p">.</span><span class="nf">to_i</span><span class="p">)</span>
</code></pre>
<p>tool/jisx0208.rb:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="k">unless</span> <span class="mh">0x8140</span> <span class="o"><=</span> <span class="n">sjis</span> <span class="o">&&</span> <span class="n">sjis</span> <span class="o"><=</span> <span class="mh">0xFCFC</span>
</code></pre> Ruby master - Feature #14609 (Open): Let `Kernel#p` without an argument print the receiverhttps://bugs.ruby-lang.org/issues/146092018-03-16T01:29:09Zko1 (Koichi Sasada)
<a name="Abstract"></a>
<h1 >Abstract<a href="#Abstract" class="wiki-anchor">¶</a></h1>
<p><code>Kernel#p(obj)</code> prints <code>obj</code> as <code>inspect</code>ed.<br>
How about printing the receiver if an argument is not given?</p>
<a name="Background"></a>
<h1 >Background<a href="#Background" class="wiki-anchor">¶</a></h1>
<p>We recently introduced <code>yield_self</code>, which encourages block chain.</p>
<p><a href="https://zverok.github.io/blog/2018-01-24-yield_self.html" class="external">https://zverok.github.io/blog/2018-01-24-yield_self.html</a><br>
Quoting from this article, we can write method chain with blocks:</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }
.yield_self { |id| "server:#{id}" }
</code></pre>
<p>There is a small problem concerning debugging.<br>
If we want to see the intermediate values in the method/block chain, we need to insert <code>tap{|e| p e}</code>.</p>
<p>With the above example,</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.tap{|e| p e} # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.tap{|e| p e} # debug print
.yield_self { |id| "server:#{id}" }
</code></pre>
<a name="Proposal"></a>
<h1 >Proposal<a href="#Proposal" class="wiki-anchor">¶</a></h1>
<p>Let <code>obj.p</code> work the same as <code>p(obj)</code>.</p>
<p>We can replace<br>
<code>block{...}.tap{|e| p e}</code><br>
with<br>
<code>block{...}.p</code></p>
<p>For the above example, we can simply add <code>.p</code> at the end of a line:</p>
<pre><code>construct_url
.yield_self { |url| Faraday.get(url) }.body
.yield_self { |response| JSON.parse(response) }.p # debug print
.dig('object', 'id')
.yield_self { |id| id || '<undefined>' }.p # debug print
.yield_self { |id| "server:#{id}" }
</code></pre>
<a name="Compatibility-issues"></a>
<h1 >Compatibility issues<a href="#Compatibility-issues" class="wiki-anchor">¶</a></h1>
<p>(1) Shorthand for <code>nil</code></p>
<p>This spec change can introduce compatibility issues because <code>p</code> returns <code>nil</code> and does not output anything.<br>
That is to say, <code>p</code> is a shorthand for <code>nil</code>. Some code-golfers use it.</p>
<p>Maybe we can ignore them :p</p>
<p>(2) make it a public method</p>
<p><code>Kernel#p</code> a is private method, so if we mistype <code>obj.x</code> as <code>obj.p</code> (not sure how it is feasible), it will raise a <code>NoMethodError</code> because of visibility.<br>
We need to change this behavior.</p>
<a name="Note"></a>
<h1 >Note<a href="#Note" class="wiki-anchor">¶</a></h1>
<a name="Past-proposal-and-discussion"></a>
<h2 >Past proposal and discussion<a href="#Past-proposal-and-discussion" class="wiki-anchor">¶</a></h2>
<p>Endoh-san proposed the same idea 10+ years ago <a href="https://blade.ruby-lang.org/ruby-dev/29736">[ruby-dev:29736]</a> in Japanese.<br>
I think we should revisit this idea because of <code>yield_self</code> introduction.</p>
<p>In this thread, Matz said "simple <code>p</code> shows <code>p(self)</code>, it is not clear".</p>
<p><a href="https://blade.ruby-lang.org/ruby-dev/30903">[ruby-dev:30903]</a></p>
<pre><code> p
はどう動くのかとか(p selfと同じ、は変な気が)
self.p(obj)
はどうなのかとか。その辺が解決(納得)できたら、ということで。
</code></pre>
<p>English translation:</p>
<pre><code>What would the behavior of:
p
be? (I feel strange for it to be equivalent to `p(self)`.) What would happen to
self.p(obj)
</code></pre>
<a name="pp"></a>
<h2 >pp<a href="#pp" class="wiki-anchor">¶</a></h2>
<p>If this proposal is accepted, we also need to change the behavior of <code>pp</code>.</p>
<a name="gems"></a>
<h2 >gems<a href="#gems" class="wiki-anchor">¶</a></h2>
<p><code>tapp</code> method is provided by a gem.<br>
<a href="https://github.com/esminc/tapp" class="external">https://github.com/esminc/tapp</a></p>
<p>I thought about proposing this method in core. But I found that <code>p</code> is shorter than <code>tapp</code>.<br>
A disadvantage is that <code>p</code> is too short and difficult to grep.</p> Ruby master - Feature #14548 (Open): Allow some_array&.[1] to be a valid syntaxhttps://bugs.ruby-lang.org/issues/145482018-02-23T19:59:34Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<p>Currently, Ruby allows accessing an array's index while testing whether the array is not nil with this syntax: <code>my_array&.[](1)</code>. I've always found this awkward but didn't mind about suggesting anything to improve this.</p>
<p>I was just reading about how JavaScript is probably going to support myArray?.[1] and found that it read good enough for me.</p>
<p>So I'd like to propose about the same syntax, replacing ?. with the Ruby equivalent &. instead. How does that look like to you?</p> Ruby master - Feature #14546 (Open): Hash#delete!https://bugs.ruby-lang.org/issues/145462018-02-23T18:52:02Zrringler (Ryan Ringler)
<p>Hash#delete currently returns nil if a given key is not found in the hash. It would be nice to have a way to check that the key was present in the hash. This can be accomplished with with a block, but it would be nice to have some sugar for this.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="c1"># => nil</span>
<span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">key</span><span class="o">|</span> <span class="k">raise</span> <span class="no">KeyError</span><span class="p">,</span> <span class="s2">"key not found </span><span class="si">#{</span><span class="n">key</span><span class="si">}</span><span class="s2">"</span> <span class="p">}</span> <span class="c1"># => KeyError (key not found: b)</span>
</code></pre>
<p>I'd like to propose a Hash#delete! method:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete!</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="c1"># => 'a'</span>
<span class="p">{</span> <span class="ss">a: </span><span class="s1">'a'</span> <span class="p">}.</span><span class="nf">delete!</span><span class="p">(</span><span class="ss">:b</span><span class="p">)</span> <span class="c1"># => KeyError (key not found: :b)</span>
</code></pre> Ruby master - Feature #14397 (Assigned): public, protected and private should return their argume...https://bugs.ruby-lang.org/issues/143972018-01-24T21:27:26Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<p>Matsuda-san suggested me that <code>public</code>, <code>protected</code> and <code>private</code> should return their arguments instead of <code>self</code>,<br>
to write such code:`</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="nb">require</span> <span class="s2">"finalist"</span>
<span class="c1"># see https://github.com/joker1007/finalist</span>
<span class="k">class</span> <span class="nc">Foo</span>
<span class="kp">extend</span> <span class="no">Finalist</span>
<span class="n">final</span> <span class="kp">private</span> <span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>I believe that it's reasonable request, and also believe that there is no product code which uses the return values of <code>public</code>, <code>protected</code> and <code>private</code>.<br>
Matz, how do you think about this change?<br>
The patch is attached.</p> Ruby master - Feature #14128 (Open): Introduce Hash#delete default valuehttps://bugs.ruby-lang.org/issues/141282017-11-23T14:18:23Zgshutler (Garry Shutler)
<p>Mirror <code>Hash#fetch(key [, default]) → obj</code> with <code>Hash#delete(key [, default]) → obj</code>.</p>
<p>Allows for more concise extraction of a value from a hash with a default.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Currently</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:a</span><span class="p">)</span> <span class="p">{</span> <span class="mi">10</span> <span class="p">}</span>
<span class="c1"># Becomes</span>
<span class="n">a</span> <span class="o">=</span> <span class="nb">hash</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="ss">:a</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</code></pre> Ruby master - Feature #13129 (Assigned): Refinements cannot refine method_missing and respond_to_...https://bugs.ruby-lang.org/issues/131292017-01-14T17:21:59Zmatsuda (Akira Matsuda)ronnie@dio.jp
<p>Refinements with method_missing and respond_to_missing? behaves very strangely.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">C</span><span class="p">;</span> <span class="k">end</span>
<span class="n">using</span> <span class="no">Module</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span>
<span class="n">refine</span> <span class="no">C</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">x</span><span class="p">()</span> <span class="nb">p</span><span class="ss">:x</span><span class="p">;</span> <span class="k">end</span>
<span class="k">def</span> <span class="nf">method_missing</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span> <span class="p">?</span> <span class="nb">p</span><span class="p">(</span><span class="ss">:fooo!</span><span class="p">)</span> <span class="p">:</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">respond_to_missing?</span><span class="p">(</span><span class="n">m</span><span class="p">,</span> <span class="n">include_private</span> <span class="o">=</span> <span class="kp">false</span><span class="p">)</span>
<span class="p">(</span><span class="n">m</span> <span class="o">==</span> <span class="ss">:foo</span><span class="p">)</span> <span class="o">||</span> <span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="p">}</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">x</span>
<span class="nb">p</span> <span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">respond_to?</span> <span class="ss">:foo</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">foo</span>
</code></pre>
<p>The script above doesn't respond_to :foo nor run :foo as expected.<br>
Actually, the result differs between ruby versions.</p>
<pre><code>% ruby -v t.rb
ruby 2.5.0dev (2017-01-14 trunk 57328) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f90ca0fb240> (NoMethodError)
% ruby -v t.rb
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007f80ae097780> (NoMethodError)
% ruby -v t.rb
ruby 2.3.3p222 (2016-11-21 revision 56859) [x86_64-darwin15]
:x
false
t.rb:19:in `<main>': undefined method `foo' for #<C:0x007fd89c83b518> (NoMethodError)
% ruby -v t.rb
ruby 2.2.6p396 (2016-11-15 revision 56800) [x86_64-darwin15]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.1.10p492 (2016-04-01 revision 54464) [x86_64-darwin15.0]
:x
false
:fooo!
% ruby -v t.rb
ruby 2.0.0p648 (2015-12-16 revision 53162) [x86_64-darwin15.6.0]
t.rb:4: warning: Refinements are experimental, and the behavior may change in future versions of Ruby!
:x
false
:fooo!
</code></pre>
<p>What I can tell is that method_missing was broken at somewhere in between 2.2 and 2.3, and respond_to_missing? has never worked correctly.</p> Ruby master - Feature #12543 (Assigned): explicit tail call syntax: foo() then returnhttps://bugs.ruby-lang.org/issues/125432016-07-02T17:24:19Zmame (Yusuke Endoh)mame@ruby-lang.org
<p>How about introducing a new syntax for tail call?</p>
<pre><code>def foo()
foo()
end
foo() #=> stack level too deep
</code></pre>
<pre><code>def bar()
bar() then return
end
bar() #=> infinite loop
</code></pre>
<ul>
<li>no new keyword (cf. <code>goto foo()</code>)</li>
<li>no conflict with any existing syntax</li>
<li>an experimental patch is available (attached)</li>
<li>no shift/reduce nor reduce/reduce conflict in parse.y</li>
</ul>
<p>--<br>
Yusuke Endoh <a href="mailto:mame@ruby-lang.org" class="email">mame@ruby-lang.org</a></p> Ruby master - Feature #12306 (Open): Implement String #blank? #present? and improve #strip and fa...https://bugs.ruby-lang.org/issues/123062016-04-20T23:33:04Zsam.saffron (Sam Saffron)sam.saffron@gmail.com
<p>Time and again there have been rejected feature requests to Ruby core to implement <code>blank</code> and <code>present</code> protocols across all objects as ActiveSupport does. I am fine with this call and think it is fair.</p>
<p>However, for the narrow case of String having <code>#blank?</code> and <code>#present?</code> makes sense.</p>
<ul>
<li>
<p>Provides a natural extension over <code>#strip</code>, <code>#lstrip</code> and <code>#rstrip</code>. <code>(" ".strip.length == 0) == " ".blank?</code></p>
</li>
<li>
<p>Plays nicely with ActiveSupport, providing an efficient implementation in Ruby core: see: <a href="https://github.com/SamSaffron/fast_blank" class="external">https://github.com/SamSaffron/fast_blank</a>, implementing blank efficiently requires a c extension.</p>
</li>
</ul>
<p>However, if this work is to be done, <code>#strip</code> and should probably start dealing with unicode blanks, eg:</p>
<pre><code>irb(main):008:0> [0x3000].pack("U")
=> " "
irb(main):009:0> [0x3000].pack("U").strip.length
=> 1
</code></pre>
<p>So there are 2 questions / feature requests here</p>
<ol>
<li>Can we add blank? and present? to String?</li>
<li>Can we amend strip and family to account for unicode per: <a href="https://github.com/SamSaffron/fast_blank/blob/master/ext/fast_blank/fast_blank.c#L43-L74" class="external">https://github.com/SamSaffron/fast_blank/blob/master/ext/fast_blank/fast_blank.c#L43-L74</a>
</li>
</ol> Ruby master - Feature #12244 (Open): Add a way to `integer - integer % num`https://bugs.ruby-lang.org/issues/122442016-04-02T13:45:33Znaruse (Yui NARUSE)naruse@airemix.jp
<p>We sometimes calculates <code>integer - integer % num</code>.</p>
<p>For example time series events into time partitions, we write code like</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">event</span> <span class="c1"># {time: 1459580435, name: "hoge", text: "Rawr!"}</span>
<span class="n">partition</span> <span class="o">=</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">-</span> <span class="n">event</span><span class="p">[</span><span class="ss">:time</span><span class="p">]</span> <span class="o">%</span> <span class="n">num</span>
<span class="n">chunk</span> <span class="o">=</span> <span class="n">get_chunk</span><span class="p">(</span><span class="n">partition</span><span class="p">)</span>
<span class="n">chunk</span><span class="p">.</span><span class="nf">write</span> <span class="n">event</span>
</code></pre>
<p><a href="https://twitter.com/tagomoris/status/715814050534461440" class="external">https://twitter.com/tagomoris/status/715814050534461440</a><br>
<a href="https://twitter.com/tagomoris/status/715814961260457985" class="external">https://twitter.com/tagomoris/status/715814961260457985</a></p>
<p>The name is always issue.<br>
There are some suggestions likes Integer#adjust](<a href="https://twitter.com/cocoatomo/status/716088708655489024" class="external">https://twitter.com/cocoatomo/status/716088708655489024</a>).</p>
<p>kosaki says <a href="https://twitter.com/kosaki55tea/status/716059296186765312" class="external">Excel's FLOOR() function is FLOOR(number, significance)</a>.<br>
Therefore Ruby should be <a href="https://twitter.com/kosaki55tea/status/716106530114768897" class="external">Integer#floor(digits=1, significance: nil)</a>.<br>
<a href="https://twitter.com/kosaki55tea/status/716107516409581568" class="external">kosaki agrees this</a>.</p>
<p>I checked the speed of a half baked implementation..., but it's 10x slow...</p>
<pre><code>% time ./miniruby -e'i=10000000;while i>0;i-=1;1459497599.floor(significance: 3600);end'
./miniruby 6.58s user 0.02s system 99% cpu 6.596 total
#3 1459604131 22:35:31 naruse@windy:~/obj/ruby
% time ./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end'
./miniruby -e'i=10000000;while i>0;i-=1;t=1459497599;t-t%3600;end' 0.52s user 0.00s system 99% cpu 0.520 total
</code></pre>
<pre><code class="diff syntaxhl" data-language="diff"><span class="gh">diff --git a/numeric.c b/numeric.c
index 37217a1..f6acfe3 100644
</span><span class="gd">--- a/numeric.c
</span><span class="gi">+++ b/numeric.c
</span><span class="p">@@ -4123,6 +4123,42 @@</span> int_dotimes(VALUE num)
<span class="err">
</span> /*
* call-seq:
<span class="gi">+ * int.floor([ndigits]) -> integer or float
+ *
+ * Rounds +int+ to a given precision in decimal digits (default 0 digits).
+ *
+ * Precision may be negative. Returns a floating point number when +ndigits+
+ * is positive, +self+ for zero, and round down for negative.
+ *
+ * 1.round #=> 1
+ * 1.round(2) #=> 1.0
+ * 15.round(-1) #=> 20
+ */
+
+static VALUE
+int_floor(int argc, VALUE* argv, VALUE num)
+{
+ static ID keyword_ids[1];
+ VALUE kwargs[1], ndigits, opt;
+ if (!keyword_ids[0]) {
+ CONST_ID(keyword_ids[0], "significance");
+ }
+
+ rb_scan_args(argc, argv, "01:", &ndigits, &opt);
+ if (!NIL_P(opt)) {
+ VALUE factor;
+ long a, b;
+ rb_get_kwargs(opt, keyword_ids, 0, 1, kwargs);
+ factor = kwargs[0];
+ a = FIX2LONG(num);
+ b = FIX2LONG(factor);
+ return LONG2FIX(a - a % b);
+ }
+ return Qnil;
+}
+
+/*
+ * call-seq:
</span> * int.round([ndigits]) -> integer or float
*
* Rounds +int+ to a given precision in decimal digits (default 0 digits).
<span class="p">@@ -4321,7 +4357,7 @@</span> Init_Numeric(void)
rb_define_method(rb_cInteger, "to_i", int_to_i, 0);
rb_define_method(rb_cInteger, "to_int", int_to_i, 0);
rb_define_method(rb_cInteger, "to_f", int_to_f, 0);
<span class="gd">- rb_define_method(rb_cInteger, "floor", int_to_i, 0);
</span><span class="gi">+ rb_define_method(rb_cInteger, "floor", int_floor, -1);
</span> rb_define_method(rb_cInteger, "ceil", int_to_i, 0);
rb_define_method(rb_cInteger, "truncate", int_to_i, 0);
rb_define_method(rb_cInteger, "round", int_round, -1);
</code></pre> Ruby master - Feature #12019 (Open): Better low-level support for writing concurrent librarieshttps://bugs.ruby-lang.org/issues/120192016-01-25T19:16:25Zpitr.ch (Petr Chalupa)
<p>Nowadays, almost every processor has more than one core. Therefore it becomes more and more important for languages to have good support of concurrent and/or parallel computation. Currently Ruby supports concurrency mainly through high-level classes: <code>Thread</code>, <code>Queue</code>, <code>Mutex</code>, <code>Monitor</code>, <code>ConditionVariable</code>.</p>
<p>This work is not colliding with plans for Ruby 3 (to provide an easy-to-use and safe concurrent abstraction to Ruby users). Following proposals suggest several key low-level Ruby extensions which will allow those interested in these topics to create fast concurrency abstractions (gems) for Ruby community, providing more choices and complementing the effort of Ruby 3. The proposed APIs are not expected to be used for every day programming but rather by concurrency enthusiast.</p>
<p>This issue is intended to serve as an aggregator for other various proposals described in following issues.</p> Ruby master - Feature #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 #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 #10481 (Assigned): Add "if" and "unless" clauses to rescue statementshttps://bugs.ruby-lang.org/issues/104812014-11-05T19:20:10Zjavawizard (Alex Boyd)alex@opengroove.org
<p>I'd like to propose a syntax change: allow boolean "if" and "unless" clauses to follow a rescue statement.</p>
<p>Consider the following:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span>
<span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">else</span>
<span class="k">raise</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>This is a fairly common way of dealing with exceptions where some condition above and beyond the exception's type determines whether the exception should be rescued. It's verbose, though, and it's not obvious at first glance exactly what conditions are being rescued, especially if "...handle error..." is more than a few lines long. I propose that the following be allowed:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>"unless" would, of course, be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">unless</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>A rescue statement whose boolean condition failed would be treated the same as if the exception being raised didn't match the exception being rescued, and move on to the next rescue statement:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">1</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">1</span><span class="o">...</span>
<span class="k">rescue</span> <span class="no">SomeError</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">error_code</span> <span class="o">==</span> <span class="mi">2</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span> <span class="n">code</span> <span class="mi">2</span><span class="o">...</span>
<span class="k">end</span>
</code></pre>
<p>And finally, catch-all rescue statements would be allowed as well:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">begin</span>
<span class="o">...</span>
<span class="k">rescue</span> <span class="o">=></span> <span class="n">e</span> <span class="k">if</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span> <span class="o">==</span> <span class="s2">"some error"</span>
<span class="o">...</span><span class="n">handle</span> <span class="n">error</span><span class="o">...</span>
<span class="k">end</span>
</code></pre> Ruby master - Feature #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 #9023 (Assigned): Array#tailhttps://bugs.ruby-lang.org/issues/90232013-10-15T13:28:25Zfuadksd (Fuad Saud)fuadksd@gmail.com
<p>I propose the addition of a <code>tail</code> method to the Array class that returns all elements but the first. It is a pretty common pattern in functional programming, but not limited to - I use it extensively in all kinds of apps/gems. The implementation would be pretty trivial, I won't risk a patch to MRI because I'm uninitiated on ruby core matters, but powerpack gem (<a href="http://github.com/bbatsov/powerpack" class="external">http://github.com/bbatsov/powerpack</a>) implements it in ruby in terms of slices.</p> Ruby master - Feature #8850 (Assigned): Convert Rational to decimal stringhttps://bugs.ruby-lang.org/issues/88502013-09-02T10:02:36Znaruse (Yui NARUSE)naruse@airemix.jp
<p>On Ruby 2.1.0, decimal literal is introduced.<br>
It generates Rational but it cannot easily convert to decimal string.<br>
You know, Rational#to_f is related to this but</p>
<ul>
<li>
<p>Float is not exact number<br>
** 0.123456789123456789r.to_f.to_s #=> "0.12345678912345678"</p>
</li>
<li>
<p>it can't handle recursive decimal<br>
** (151/13r).to_f.to_s #=> "11.615384615384615"</p>
</li>
<li>
<p>the method name<br>
** to_decimal<br>
** to_decimal_string<br>
** to_s(format: :decimal)<br>
** extend sprintf</p>
</li>
<li>
<p>how does it express recursive decimal<br>
** (151/13r).to_decimal_string #=> "11.615384..."<br>
** (151/13r).to_decimal_string #=> "11.(615384)"</p>
</li>
</ul>
<p>Example implementation is following.<br>
Its result is<br>
** 0.123456789123456789r.to_f.to_s #=> "0.123456789123456789"<br>
** (151/13r).to_f.to_s #=> "11.(615384)"</p>
<pre><code>class Rational
def to_decimal_string(base=10)
n = numerator
d = denominator
r, n = n.divmod d
str = r.to_s(base)
return str if n == 0
h = {}
str << '.'
n *= base
str.size.upto(Float::INFINITY) do |i|
r, n = n.divmod d
if n == 0
str << r.to_s(base)
break
elsif h.key? n
str[h[n], 0] = '('
str << ')'
break
else
str << r.to_s(base)
h[n] = i
n *= base
end
end
str
end
end
</code></pre> Ruby master - Feature #8839 (Assigned): Class and module should return the class or module that w...https://bugs.ruby-lang.org/issues/88392013-08-31T02:57:19Zheadius (Charles Nutter)headius@headius.com
<p>With the change for <a href="https://bugs.ruby-lang.org/issues/3753" class="external">https://bugs.ruby-lang.org/issues/3753</a>, "def" forms now return the symbolic name of the method defined. Because class and module bodies just return the last expression in their bodies, this means they will now usually end up returning a symbol for the last method defined. This does not seem useful or correct.</p>
<p>I think class and module should return a reference to the class or module just opened. This would make the return value useful and consistent.</p> Ruby master - Feature #8678 (Assigned): Allow invalid string to work with regexphttps://bugs.ruby-lang.org/issues/86782013-07-24T14:47:22Znaruse (Yui NARUSE)naruse@airemix.jp
<p>Legacy Ruby 1.8 could regexp match with broken strings.<br>
People can find characters from binary data on the age.</p>
<p>After Ruby 1.9, Ruby raises Exception if it does regexp match with broken strings.<br>
So it became hard to work with character-wise regexp matching with binary data.</p>
<p>Following patch allows it with the constant Regexp::LOOSEENCODING.</p>
<p>commit eb0111ff7ae3f563ce201c4a5f724f121336d42d<br>
Author: NARUSE, Yui <a href="mailto:naruse@ruby-lang.org" class="email">naruse@ruby-lang.org</a><br>
Date: Mon Jul 22 05:37:44 2013 +0900</p>
<pre><code>* Regexp
* New constant:
* Regexp::ENCODINGLOOSE: declare execute matching even if the target string
is invalid byte sequence. [experimental]
</code></pre>
<p>diff --git a/NEWS b/NEWS<br>
index f5fe388..ade0b03 100644<br>
--- a/NEWS<br>
+++ b/NEWS<br>
@@ -35,6 +35,11 @@ with all sufficient information, see the ChangeLog file.</p>
<ul>
<li>misc
<ul>
<li>Mutex#owned? is no longer experimental.</li>
</ul>
</li>
</ul>
<p>+* Regexp</p>
<ul>
<li>
<ul>
<li>New constant:</li>
</ul>
</li>
<li>
<ul>
<li>Regexp::ENCODINGLOOSE: declare execute matching even if the target string</li>
</ul>
</li>
<li>
<pre><code> is invalid byte sequence. [experimental]
</code></pre>
</li>
<li>
</ul>
<ul>
<li>String
<ul>
<li>New methods:
<ul>
<li>String#scrub and String#scrub! verify and fix invalid byte sequence.<br>
diff --git a/re.c b/re.c<br>
index e5cc79d..230a2e0 100644<br>
--- a/re.c<br>
+++ b/re.c<br>
@@ -256,6 +256,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)</li>
</ul>
</li>
</ul>
</li>
</ul>
<p>#define REG_LITERAL FL_USER5<br>
#define REG_ENCODING_NONE FL_USER6<br>
+#define REG_ENCODING_LOOSE FL_USER7</p>
<p>#define KCODE_FIXED FL_USER4</p>
<p>@@ -263,6 +264,7 @@ rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc)<br>
(ONIG_OPTION_IGNORECASE|ONIG_OPTION_MULTILINE|ONIG_OPTION_EXTEND)<br>
#define ARG_ENCODING_FIXED 16<br>
#define ARG_ENCODING_NONE 32<br>
+#define ARG_ENCODING_LOOSE 64</p>
<p>static int<br>
char_to_option(int c)<br>
@@ -1251,7 +1253,8 @@ rb_reg_prepare_enc(VALUE re, VALUE str, int warn)<br>
{<br>
rb_encoding *enc = 0;</p>
<ul>
<li>if (rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {</li>
</ul>
<ul>
<li>if (!(RBASIC(re)->flags & REG_ENCODING_LOOSE) &&</li>
<li>
<pre><code> rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN) {
rb_raise(rb_eArgError,
"invalid byte sequence in %s",
rb_enc_name(rb_enc_get(str)));
</code></pre>
</li>
</ul>
<p>@@ -2433,6 +2436,9 @@ rb_reg_initialize(VALUE obj, const char *s, long len, rb_encoding *enc,<br>
if (options & ARG_ENCODING_NONE) {<br>
re->basic.flags |= REG_ENCODING_NONE;<br>
}</p>
<ul>
<li>
<p>if (options & ARG_ENCODING_LOOSE) {</p>
</li>
<li>
<pre><code> re->basic.flags |= REG_ENCODING_LOOSE;
</code></pre>
</li>
<li>
<p>}</p>
<p>re->ptr = make_regexp(RSTRING_PTR(unescaped), RSTRING_LEN(unescaped), enc,<br>
options & ARG_REG_OPTION_MASK, err,<br>
@@ -3091,6 +3097,7 @@ rb_reg_options(VALUE re)<br>
options = RREGEXP(re)->ptr->options & ARG_REG_OPTION_MASK;<br>
if (RBASIC(re)->flags & KCODE_FIXED) options |= ARG_ENCODING_FIXED;<br>
if (RBASIC(re)->flags & REG_ENCODING_NONE) options |= ARG_ENCODING_NONE;</p>
</li>
<li>
<p>if (RBASIC(re)->flags & REG_ENCODING_LOOSE) options |= ARG_ENCODING_LOOSE;<br>
return options;<br>
}</p>
</li>
</ul>
<p>@@ -3579,6 +3586,8 @@ Init_Regexp(void)<br>
rb_define_const(rb_cRegexp, "FIXEDENCODING", INT2FIX(ARG_ENCODING_FIXED));<br>
/* see Regexp.options and Regexp.new */<br>
rb_define_const(rb_cRegexp, "NOENCODING", INT2FIX(ARG_ENCODING_NONE));</p>
<ul>
<li>
<p>/* see Regexp.options and Regexp.new */</p>
</li>
<li>
<p>rb_define_const(rb_cRegexp, "LOOSEENCODING", INT2FIX(ARG_ENCODING_LOOSE));</p>
<p>rb_global_variable(&reg_cache);</p>
</li>
</ul>
<p>diff --git a/string.c b/string.c<br>
index 1d784e3..caf0baf 100644<br>
--- a/string.c<br>
+++ b/string.c<br>
@@ -3970,7 +3970,7 @@ str_gsub(int argc, VALUE *argv, VALUE str, int bang)<br>
cp = sp;<br>
str_enc = STR_ENC_GET(str);<br>
rb_enc_associate(dest, str_enc);</p>
<ul>
<li>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</li>
</ul>
<ul>
<li>
<p>/<em>ENC_CODERANGE_SET(dest, rb_enc_asciicompat(str_enc) ? ENC_CODERANGE_7BIT : ENC_CODERANGE_VALID);</em>/</p>
<p>do {<br>
n++;<br>
diff --git a/test/ruby/test_regexp.rb b/test/ruby/test_regexp.rb<br>
index 11e86ec..b8f6897 100644<br>
--- a/test/ruby/test_regexp.rb<br>
+++ b/test/ruby/test_regexp.rb<br>
@@ -8,6 +8,10 @@ class TestRegexp < Test::Unit::TestCase<br>
$VERBOSE = nil<br>
end</p>
</li>
<li>
<p>def u(str)</p>
</li>
<li>
<p>str.dup.force_encoding(Encoding::UTF_8)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<p>def teardown<br>
$VERBOSE = @verbose<br>
end<br>
@@ -958,6 +962,17 @@ class TestRegexp < Test::Unit::TestCase<br>
}<br>
end</p>
</li>
<li>
<p>def test_encoding_loose</p>
</li>
<li>
<p>str = u("\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(".", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Any}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new("\u3042", Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(1, Regexp.new(u('\p{Hiragana}'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A.\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>str = u("\xf1\x80\xE3\x81\x82\x81")</p>
</li>
<li>
<p>assert_equal(0, Regexp.new(u('\A..\p{Hiragana}.\z'), Regexp::LOOSEENCODING) =~ str)</p>
</li>
<li>
<p>end</p>
</li>
<li>
<a name="This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo"></a>
<h1 >This assertion is for porting x2() tests in testpy.py of Onigmo.<a href="#This-assertion-is-for-porting-x2-tests-in-testpypy-of-Onigmo" class="wiki-anchor">¶</a></h1>
<p>def assert_match_at(re, str, positions, msg = nil)<br>
re = Regexp.new(re) unless re.is_a?(Regexp)</p>
</li>
</ul> Ruby master - Feature #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 #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 #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 #8042 (Assigned): Add Addrinfo#socket to create a socket that is not connec...https://bugs.ruby-lang.org/issues/80422013-03-08T08:35:01Zdrbrain (Eric Hodel)drbrain@segment7.net
<p>This adds a socket method to Addrinfo to get a socket that has not been bound or connected to any address for connectionless operation.</p> Ruby master - Feature #8016 (Assigned): Alias __FILE__ and __LINE__ as methodshttps://bugs.ruby-lang.org/issues/80162013-03-05T12:16:30Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
All of the previous issues discussing the new (({Kernel#<strong>dir</strong>})) method (<a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: Kernel#__dir__ (Closed)" href="https://bugs.ruby-lang.org/issues/1961">#1961</a>, <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: __DIR__ revisted (Closed)" href="https://bugs.ruby-lang.org/issues/3346">#3346</a>, <a class="issue tracker-1 status-6 priority-4 priority-default closed" title="Bug: Why __dir__, not __DIR__ (Rejected)" href="https://bugs.ruby-lang.org/issues/7975">#7975</a>), never came to any conclusion regarding the naming inconsistency between the likes of (({<strong>dir</strong>})) and (({<strong>method</strong>})), and the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})).</p>
<p>Should we not add (({<strong>file</strong>})) and (({<strong>line</strong>})) as methods also, and perhaps deprecate the keywords (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})). This would keep it consistant with all the other double-underscore methods. To most developers who perhaps do not know Ruby as intricately as most of the people on this issue tracker, the inconsistency between (({<strong>dir</strong>})) and (({<strong>FILE</strong>})) is not just confusing by name, but the fact that one is a method and one isn't, is doubly confusing. Definitely not principle of least surprise.</p>
<p>This needs to be addressed in my opinion, either through deprecation of (({<strong>FILE</strong>})) and (({<strong>LINE</strong>})), or by keeping those keywords and simply creating Kernel method equivalents for the sake of a consistant API.</p>
<p>While on the topic, someone also suggested in one of those previous issues, to give (({<strong>dir</strong>})) an optional join argument, so you could do something like this:</p>
<pre><code>__dir__('somefile.txt') # => /Users/admin/somefile.txt
</code></pre>
<p>I'd predict that at least 90% of use cases for (({<strong>dir</strong>})) will involve joining it to another path or filename. I can't see any harm in adding this. The naming inconstancies are my main concern however. This would just be a nice bonus that takes advantage of the fact that (({<strong>dir</strong>})) is a method rather than a keyword.<br>
=end</p> Ruby master - Feature #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 #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 #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 #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 #7436 (Assigned): Allow for a "granularity" flag for backtrace_locationshttps://bugs.ruby-lang.org/issues/74362012-11-26T07:06:40Zsam.saffron (Sam Saffron)sam.saffron@gmail.com
<p>related to <a href="http://bugs.ruby-lang.org/issues/7051" class="external">http://bugs.ruby-lang.org/issues/7051</a></p>
<p>Sometimes one need less information (or more information) associated with backtraces.</p>
<p>It would be nice if one could send in a separate flag informing the VM about the granularity of information required, eg:</p>
<p>caller_locations(0,-current_depth, BacktraceInfo::Label & BacktraceInfo::Lineno)</p>
<p>This allows for one to take quicker backtraces if they need less information, additionally BacktraceInfo::Bindings and BacktraceInfo::Klass could be added which allow you to gather more information for heavy profiling / diagnostics.</p> Ruby master - Feature #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 #7314 (Assigned): Convert Proc to Lambda doesn't work in MRIhttps://bugs.ruby-lang.org/issues/73142012-11-09T01:30:19Zschneems (Richard Schneeman)
<p>I have code where I need to convert a proc to a lambda (i need to be able to return out of the block). I would expect that passing a proc into a lambda to return a lambda. When I run this code on MRI i do not get the result I would expect</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">my_proc</span> <span class="o">=</span> <span class="nb">proc</span> <span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="p">}</span>
<span class="n">my_lambda</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="o">&</span><span class="n">my_proc</span>
<span class="n">my_lambda</span><span class="p">.</span><span class="nf">lambda?</span>
</code></pre>
<p>The result is <code>false</code> but I would expect it to be <code>true</code></p>
<p>There is currently a way to turn a proc into a lambda in MRI like this:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">convert_to_lambda</span> <span class="o">&</span><span class="n">block</span>
<span class="n">obj</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="n">obj</span><span class="p">.</span><span class="nf">define_singleton_method</span><span class="p">(</span><span class="ss">:_</span><span class="p">,</span> <span class="o">&</span><span class="n">block</span><span class="p">)</span>
<span class="k">return</span> <span class="n">obj</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:_</span><span class="p">).</span><span class="nf">to_proc</span>
<span class="k">end</span>
</code></pre>
<p>But this feels like a hack, and is not supported across other implementations. I would expect that passing a proc into a lambda to return a lambda, I believe it is a bug.</p> Ruby master - Feature #7132 (Assigned): Alternation between named / ordered method arguments and ...https://bugs.ruby-lang.org/issues/71322012-10-09T21:17:44ZAnonymous
<p>=begin<br>
Hi everyone. I am using Ruby for >1 year and I would like to share with you my dreams regarding the named method arguments planned for 2.0. Let us imagine a class Thief with 3 properties (name, hit_points and dexterity), which has constructor #new_thief:</p>
<pre><code>new_thief name: "John Fingers", hit_points: 14, dexterity: 15
</code></pre>
<p>I dream about this constructor accepting alternative syntax:</p>
<pre><code>new_thief "John Fingers", hit_points: 14, dexterity: 15
</code></pre>
<p>and accepting synonyms (aliases) :hp for :hit_points and :dex for dexterity:</p>
<pre><code>new_thief "John Fingers", hp: 14, dex: 15
</code></pre>
<p>To explain my motivation, I am creating a DSL in biology. I am facing the challenge of explaining to my colleagues why is it better than their current Java app. Biologists love synonyms, and I'd like the users calling constructors for biological objects to have freedom to use the synonym they like. Of course, I can already achieve it in 1.9.3:</p>
<pre><code>def new_thief *args
oo = args.extract_options!
raise ArgumentError if args[0] and oo[:name] and args[0] != oo[:name]
name = args[0] || oo[:name] || "John Doe"
raise ArgumentError if oo[:hp] and oo[:hit_points] and oo[:hp] != oo[:hit_points]
hp = oo[:hp] || oo[:hit_points] || 9
raise ArgumentError if oo[:dex] and oo[:dexterity] and oo[:dex] != oo[:dexterity]
dex = oo[:dex] || oo[:dexterity] || 11
Thief.new( name: name, hit_points: hp, dexterity: dex )
end
</code></pre>
<p>But I find myself doing this over and over, and even if I write a library to make it easier, it's still too cumbersome.</p>
<p>Proposal no. 1: I propose that alternation between named / ordered arguments and aliases (synonyms) for named method arguments be catered for already by core syntax.</p>
<p>Proposal no. 2: I propose that the syntax for this be as follows:</p>
<pre><code>def new_thief( name=**:name="John Doe", hp: **:hit_points=14, dex: **:dexterity=15 )
Thief.new name: name, hit_points: hp, strength: str, dexterity: dex
end
</code></pre>
<p>where expressions **:arg_name would refer to the named argument :arg_name.</p>
<p>Please judge the two proposals independently. I really dream about having the alternation between named / ordered arguments and aliases for named arguments in Ruby 2.0. But I feel less sure that the syntax **:arg_name that I am proposing is the best possible syntax for this. Mind me, I don't think it is bad, I am just not sure it is <em>best</em>.</p>
<p>PS: Please forgive me suggesting such a complicated feature, while being unable to write a single line in C.<br>
=end</p> 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 #7087 (Assigned): ::ConditionVariable#wait does not work with Monitor becau...https://bugs.ruby-lang.org/issues/70872012-09-30T00:19:32Zrklemme (Robert Klemme)shortcutter@googlemail.com
<p>See program attached to bug <a class="issue tracker-2 status-2 priority-4 priority-default" title="Feature: ConditionVariable#wait has meaningless return value (Assigned)" href="https://bugs.ruby-lang.org/issues/7086">#7086</a>: timeout_4 always throws:</p>
<p>ERROR: method "timeout_4": #<NoMethodError: private method `sleep' called for #<a href="Monitor:0x87e49f8" class="external">Monitor:0x87e49f8</a>></p>
<p>$ irb19 -r monitor<br>
irb(main):001:0> Monitor.new.method(:sleep)<br>
=> #<Method: Monitor(Kernel)#sleep><br>
irb(main):002:0> Monitor.instance_methods.grep /sleep/<br>
=> []</p> Ruby master - Feature #6842 (Assigned): Add Optional Arguments to String#striphttps://bugs.ruby-lang.org/issues/68422012-08-07T20:24:20Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
One of the very few things I miss from the ol' php days many years ago, was the ability to easily strip arbitrary characters from the ends of string using trim(). Typically, this is whitespace characters, and #strip currently fulfils that use case, but there are also instances where it'd be nice to be able to strip any range of characters from the ends of a string. It goes well with Array#join as often when joining strings with a delimiter, you want to make sure those strings don't already begin or end with that character.</p>
<p>For a full-featured #strip, I'd like to see it have the option of accepting both an Array or String. If a string is provided, each character in that string will be stripped. If an array of strings is given, each element of the array is stripped from the ends of the string - this allows for multi-character delimiters for example. Of course you could go really nuts and supports regex as well (or instead of arrays). To demonstrate the difference...</p>
<pre><code>"<b>bold text</b>".strip("</b>") #=> "old text"
"<b>bold text</b>".strip(["<b>", "</b>"]) #=> "bold text"
"<em><b>bold text</b></em>".strip(["<b>", "</b>", "<em>", "</em>"]) #=> "bold text"
"<em><b>bold text</b></em>".strip(/<\/?.+?>/) #=> "bold text"
</code></pre>
<p>A simple real-world example; this is actually what I was wanting to do right before I came here to raise this feature request, but there's been all kinds of other use cases I've hit in the past:</p>
<pre><code>['some', '/chunked', 'path/'].map{ |v| v.strip('/') }.join('/') #=> "some/chunked/path"
</code></pre>
<p>File#join does something similar, but when you need control over the joining character, this is the way you'd do it.</p>
<p>I've lost count of how many times I've wanted this in Ruby, and there's really no nice workaround. Here's an example on StackOverflow of someone asking how to achieve this stripping behaviour in ruby: <a href="http://stackoverflow.com/questions/3453262/how-to-strip-leading-and-trailing-quote-from-string-in-ruby" class="external">http://stackoverflow.com/questions/3453262/how-to-strip-leading-and-trailing-quote-from-string-in-ruby</a></p>
<p>Obviously, you'd do the same for #lstrip and #rstrip, and all the mutable variants (#strip!, #lstrip!, #rstrip!). Looking forward to others thoughts on this one.<br>
=end</p> 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 #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 #6611 (Assigned): Comments requested on implementation of set_parse_funchttps://bugs.ruby-lang.org/issues/66112012-06-20T07:46:26Zcjheath (Clifford Heath)clifford.heath@gmail.com
<p>Folk,</p>
<p>I've implemented Twister, a new mutation testing tool to replace Heckle.<br>
It relies on a new hook into the Ruby parser, in order to modify what the<br>
parser thinks it has seen.</p>
<p>Although I have written C extensions before, there are some aspects of<br>
the Ruby core which I'm unfamiliar with and as a result don't know the right<br>
way to handle. I'd like your comments, suggestions and improvements<br>
please.</p>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db</a></p>
<p>In particular, I'd like to know the following:</p>
<ol>
<li>Do you prefer that I move the literal strings (which occur once each) to #defined?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R1003" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R1003</a></p>
<ol start="2">
<li>Will this line of code mess up the GC, and how should I fix that?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R3853" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R3853</a></p>
<ol start="3">
<li>The set_parse_func is extern though it should be static, but I need to move<br>
the rb_define_global_function out of thread.c. Can someone please tell me where I should<br>
move it to, since there is no Init_Parser?</li>
</ol>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R9029" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L1R9029</a></p>
<p><a href="https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L3R4705" class="external">https://github.com/cjheath/ruby/commit/ea99527feaf7dd06b3e8433ec640238441b188db#L3R4705</a></p>
<ol start="4">
<li>I think I should change set_parse_func to accept a flags argument and a block,<br>
instead of assuming all flags, and taking a Proc. What are the downsides of using a<br>
block instead of a Proc (does this reduce the number of Bindings that get created)?<br>
How do I change set_parse_func to use a block?</li>
</ol>
<p>The initial implementation of Twister is an extension to RSpec which adds the option<br>
"--twist file-or-dir". It's still a bit rough - it needs to change the reporting on the twisted<br>
runs that follow the first (untwisted) run - but it does prove then concept.</p>
<p>Clifford Heath, Data Constellation, <a href="http://dataconstellation.com" class="external">http://dataconstellation.com</a><br>
Agile Information Management and Design.</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 #6452 (Assigned): Allow extend to override class methodshttps://bugs.ruby-lang.org/issues/64522012-05-19T01:58:25Zrosenfeld (Rodrigo Rosenfeld Rosas)rr.rosas@gmail.com
<pre><code>module A
def self.a
'a1'
end
end
module B
def a
'a2'
end
def b
'b'
end
end
A.extend B
assert A.a == 'a2' # this is the change I'm proposing - currently it is 'a1'
assert A.b == 'b'
</code></pre>
<p>Would this change be possible for 3.0?</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 #6309 (Assigned): Add a reference queue for weak referenceshttps://bugs.ruby-lang.org/issues/63092012-04-17T17:10:15Zheadius (Charles Nutter)headius@headius.com
<p>Most interesting uses of WeakRef are much harder to do efficiently without a reference queue.</p>
<p>A reference queue, as implemented by the JVM, is basically a queue into which weak references are placed some time after the object they refer to has been collected. The queue can be polled cheaply to look for collected references.</p>
<p>A simple example of usage can be seen in the weakling gem, with an efficient implementation of an ID hash: <a href="https://github.com/headius/weakling/blob/master/lib/weakling/collections.rb" class="external">https://github.com/headius/weakling/blob/master/lib/weakling/collections.rb</a></p>
<p>Notice the _cleanup method is called for every operation, to keep the hash clear of dead references. Failure to have a _cleanup method would mean the hash grows without bounds.</p>
<p>_cleanup cannot be implemented efficiently on MRI at present because there's no reference queue implementation. On MRI, _cleanup would have to perform a linear scan of all stored values periodically to search for dead references. For a heavily used hash with many live values, this becomes a very expensive operation.</p>
<p>It's probably possible to implement reference queues efficiently atop the new ObjectSpace::WeakMap internals, since it already keeps track of weak references and can run code when a weak reference no longer refers to a live object.</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 #5970 (Assigned): Add Enumerable#join with same semantics as Array#joinhttps://bugs.ruby-lang.org/issues/59702012-02-05T17:27:39Znow (Nikolai Weibull)now@disu.se
<p>Currently, to join the elements of an Enumerable, you need to call #to_a on the Enumerable and then #join the result. With Enumerable#join one wouldn’t need need to create an intermediate Array.</p> Ruby master - Feature #5945 (Assigned): Add the ability to mark a at_exit as process-local. https://bugs.ruby-lang.org/issues/59452012-01-30T09:59:36Zrobertgleeson (Robert Gleeson)
<p>I'd like to propose a enhancement to <code>at_exit</code>.<br>
It would be nice if you could stop a <code>at_exit</code> handler from running in subprocesses.<br>
You can do this manually with this code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">parent</span> <span class="o">=</span> <span class="no">Process</span><span class="p">.</span><span class="nf">pid</span>
<span class="nb">at_exit</span> <span class="k">do</span>
<span class="k">if</span> <span class="n">parent</span> <span class="o">==</span> <span class="no">Process</span><span class="p">.</span><span class="nf">pid</span>
<span class="c1"># …</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>You can also do it by bypassing handlers:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">at_exit</span> <span class="k">do</span>
<span class="c1"># …</span>
<span class="k">end</span>
<span class="nb">fork</span> <span class="k">do</span>
<span class="nb">exit!</span>
<span class="k">end</span>
</code></pre>
<p>But it would be nice if I could do:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">at_exit</span><span class="p">(</span><span class="kp">false</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># …</span>
<span class="k">end</span>
</code></pre>
<p>The first approach is kind of ugly, and the second approach isn't sustainable if code outside<br>
your control can <code>fork(…)</code> without calling <code>exit!</code>.</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 #5582 (Assigned): Allow clone of singleton methods on a BasicObjecthttps://bugs.ruby-lang.org/issues/55822011-11-07T12:34:13Zthinkerbot (Simon Chiang)simon.a.chiang@gmail.com
<p>Currently I do not know of a way to implement something like 'clone' on a BasicObject subclass. This is as close as I've gotten but as you can see the singleton methods are not propagated to the clone.</p>
<pre><code>require 'test/unit'
class Context < BasicObject
def _singleton_class_
class << self
SINGLETON_CLASS = self
def _singleton_class_
SINGLETON_CLASS
end
end
_singleton_class_
end
def _class_
_singleton_class_.superclass
end
def _extend_(mod)
mod.__send__(:extend_object, self)
end
def _initialize_clone_(orig)
# set variables as needed
end
def _clone_
clone = _class_.allocate
clone._initialize_clone_(self)
_singleton_class_.included_modules.each {|mod| clone._extend_ mod }
clone
end
end
class ContextTest < Test::Unit::TestCase
module A
def a
:a
end
end
def test__clone__inherits_modules
context = Context.new
context._extend_ A
clone = context._clone_
assert_equal :a, clone.a
end
def test__clone__inherits_singleton_methods
context = Context.new
def context.a
:a
end
clone = context._clone_
assert_equal :a, clone.a # fails
end
end
</code></pre>
<p>Is there a way to do this that I don't see? If not, then I request that a way be added - perhaps by allowing the singleton_class to be set somehow.</p>
<p>In my case I am using Context as the context for a dsl where methods write to a target (an instance variable). I want to be able to clone a context such that I can have multiple contexts with the same methods, including extensions and singletons, that write to different targets.</p>
<p>Thank you.</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 #5129 (Assigned): Create a core class "FileArray" and make "ARGF" its instancehttps://bugs.ruby-lang.org/issues/51292011-08-01T13:57:46Zyimutang (Joey Zhou)
<p>I suggest to create a class "<code>FileArray</code>" whose instance behaves just like <code>ARGF</code> do.<br>
And I think <code>ARGF</code> should be an instance of <code>FileArray</code>. Now when I "<code>p ARGF.class</code>", I get "<code>ARGF.class</code>", so <code>ARGF</code> is an instance of <code>ARGF.class</code>, how meaningless it is.</p>
<p>FileArray methods:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># create an instance</span>
<span class="n">fa</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="s1">'a.txt'</span><span class="p">,</span><span class="s1">'b.txt'</span><span class="p">,</span><span class="s1">'c.txt'</span><span class="p">)</span>
<span class="c1"># take many methods from IO</span>
<span class="c1"># most methods from ARGF should be instance methods of ARGF </span>
<span class="n">fa</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span><span class="o">|</span><span class="n">line</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">line</span> <span class="p">}</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">realines</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">filename</span> <span class="c1"># current file</span>
<span class="c1"># but "argv" not</span>
<span class="nb">p</span> <span class="n">fa</span><span class="p">.</span><span class="nf">file_list</span> <span class="c1"># in ARGF, its ARGF.argv, but #argv is not a proper name for FileArray</span>
<span class="c1"># ARGV array can be modified, adding new file into it, all replace to a new file list.</span>
<span class="c1"># FileArray should add some methods to modify the inner file list.</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">insert</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="s2">"d.txt"</span><span class="p">)</span>
<span class="n">fa</span><span class="p">.</span><span class="nf">delete</span><span class="p">(</span><span class="s1">'a.txt'</span><span class="p">)</span>
</code></pre>
<p>With <code>FileArray</code>, You can create multiple <code>ARGF</code>-like file arrays simultaneously.</p>
<p>For example, I want to mix two <em>groups</em> of files, not two files:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a_files</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="o">*</span><span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'a*.txt'</span><span class="p">))</span>
<span class="n">b_files</span> <span class="o">=</span> <span class="no">FileArray</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="o">*</span><span class="no">Dir</span><span class="p">.</span><span class="nf">glob</span><span class="p">(</span><span class="s1">'b*.txt'</span><span class="p">))</span>
<span class="n">enum_a</span> <span class="o">=</span> <span class="n">a_files</span><span class="p">.</span><span class="nf">each</span>
<span class="n">enum_b</span> <span class="o">=</span> <span class="n">b_files</span><span class="p">.</span><span class="nf">each</span>
<span class="kp">loop</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="n">enum_a</span><span class="p">.</span><span class="nf">next</span>
<span class="nb">puts</span> <span class="n">enum_b</span><span class="p">.</span><span class="nf">next</span>
<span class="k">end</span>
</code></pre> 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 #4818 (Assigned): Add method marshalable?https://bugs.ruby-lang.org/issues/48182011-06-03T11:07:15Zyimutang (Joey Zhou)
<p>Some objects can not be marshaled. Maybe there should be a method to tell it.</p>
<p>hash = Hash.new {|h,k| k * 2}</p>
<p>this hash can't be marshaled because it has a default proc. If existing such method:</p>
<p>Marshal.marshalable?(hash) #=> method "Marshal.marshalable?"<br>
hash.marshalable? #=> method "Kernel#marshalable?"</p>
<p>If you think the method name hard to spell, maybe get a synonym "dumpable?"</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 #4539 (Assigned): Array#zip_withhttps://bugs.ruby-lang.org/issues/45392011-03-30T06:21:32Zcitizen428 (Michael Kohl)citizen428@gmail.com
<p>Inspired by Haskell's <code>zipWith</code> function, I hacked on together for Ruby:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">].</span><span class="nf">zip_with</span><span class="p">([</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">],</span> <span class="p">:</span><span class="o">+</span><span class="p">)</span> <span class="c1">#=> [7, 7, 7]</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="nf">zip_with</span><span class="p">([</span><span class="mi">6</span><span class="p">,</span><span class="mi">5</span><span class="p">,</span><span class="mi">4</span><span class="p">])</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="p">,</span><span class="n">b</span><span class="o">|</span> <span class="mi">3</span><span class="o">*</span><span class="n">a</span><span class="o">+</span><span class="mi">2</span><span class="o">*</span><span class="n">b</span> <span class="p">}</span> <span class="c1">#=> [15, 16, 17]</span>
</code></pre>
<p>So far I only have a Ruby version of it:</p>
<p><a href="https://gist.github.com/731702b90757e21cadcb" class="external">https://gist.github.com/731702b90757e21cadcb</a></p>
<p>My questions:</p>
<ol>
<li>
<p>Would this method be considered a worthwhile addition to <code>Array</code>?</p>
</li>
<li>
<p>I've never hacked on the C side of Ruby (read some parts of the source though) and my C is quite rusty. I'd like to change that, would somebody be willing to help me turn this into a proper patch?</p>
</li>
</ol> 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> Ruby master - Feature #4514 (Assigned): #deep_clone and #deep_dup for Objectshttps://bugs.ruby-lang.org/issues/45142011-03-21T19:23:02Zwardrop (Tom Wardrop)tom@tomwardrop.com
<p>=begin<br>
There's often a need to do a deep clone of an object, especially of Hash/Array trees. The typical work around to the lack of this functionality is to Marshall and then Unmarshall (e.g. Marshal::load(Marshal::dump(self)) ), which incurs more overhead than it probably should, and is not very semantic. My suggestion is to either provide #deep_clone and #deep_dup methods on the Object class, or to at least provide equivalent functionality for Hashes and Arrays, such as possibly a #deep_merge method for Hash. The exact implantation is not a large concern of mine; I'll let the experts determine the best method of achieving the desired outcome.<br>
=end</p>