Ruby Issue Tracking System: Issues
https://bugs.ruby-lang.org/
https://bugs.ruby-lang.org/favicon.ico?1711330511
2021-01-31T17:09:39Z
Ruby Issue Tracking System
Redmine
Ruby master - Bug #17600 (Closed): lib/benchmark should use `$stdout` instead of `STDOUT`
https://bugs.ruby-lang.org/issues/17600
2021-01-31T17:09:39Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Unless there is objection, I'll change all uses of <code>STDOUT</code> to <code>$stdout</code> in <code>lib/benchmark</code>, to allow redirection to other io.</p>
<p>See <a href="https://github.com/ruby/benchmark/issues/5" class="external">https://github.com/ruby/benchmark/issues/5</a></p>
Ruby master - Bug #17577 (Closed): Segfault when sending some Exceptions to a Ractor
https://bugs.ruby-lang.org/issues/17577
2021-01-24T19:03:45Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The following segfaults:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="n">receive</span> <span class="p">}</span>
<span class="k">begin</span>
<span class="n">foo</span> <span class="c1"># => raises a NoMethodError</span>
<span class="k">rescue</span> <span class="no">Exception</span> <span class="o">=></span> <span class="n">e</span>
<span class="n">r</span><span class="p">.</span><span class="nf">send</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>Note that some exceptions are ok:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">raise</span> <span class="c1"># => ok</span>
<span class="k">raise</span> <span class="no">NoMethodError</span><span class="p">,</span> <span class="s1">'...'</span> <span class="c1"># => ok</span>
<span class="s1">'s'</span><span class="p">.</span><span class="nf">to_i</span><span class="p">(</span><span class="o">-</span><span class="mi">2</span><span class="p">)</span> <span class="c1"># => ok</span>
<span class="n">foo</span> <span class="c1"># => segfault</span>
<span class="no">Xyz</span> <span class="c1"># => segfault</span>
</code></pre>
<p>Present on 3.0.0p0 as well as master (ruby 3.1.0dev (2021-01-24T14:26:11Z master 30f11e73c4) [x86_64-darwin18])</p>
<pre><code>-- Control frame information -----------------------------------------------
c:0004 p:0003 s:0019 e:000018 METHOD <internal:ractor>:583
c:0003 p:0025 s:0012 e:000011 RESCUE ractor.rb:5
c:0002 p:0025 s:0008 E:000680 EVAL ractor.rb:2 [FINISH]
c:0001 p:0000 s:0003 E:001b80 (none) [FINISH]
-- C level backtrace information -------------------------------------------
/Users/mal/.rbenv/versions/dev/bin/ruby(rb_vm_bugreport+0x732) [0x105de8672]
/Users/mal/.rbenv/versions/dev/bin/ruby(rb_bug_for_fatal_signal+0x1dc) [0x105bf671c]
/Users/mal/.rbenv/versions/dev/bin/ruby(sigsegv+0x5b) [0x105d3c87b]
/usr/lib/system/libsystem_platform.dylib(_sigtramp+0x1d) [0x7fff61425b5d]
[0x34]
/Users/mal/.rbenv/versions/dev/bin/ruby(rb_objspace_reachable_objects_from+0xa3) [0x105c19193]
/Users/mal/.rbenv/versions/dev/bin/ruby(obj_traverse_replace_i+0x38d) [0x105cedb0d]
/Users/mal/.rbenv/versions/dev/bin/ruby(obj_traverse_replace_i+0x46f) [0x105cedbef]
/Users/mal/.rbenv/versions/dev/bin/ruby(ractor_send+0x18b) [0x105ce8fdb]
/Users/mal/.rbenv/versions/dev/bin/ruby(vm_exec_core+0x77ea) [0x105dbfcaa]
/Users/mal/.rbenv/versions/dev/bin/ruby(rb_vm_exec+0xb36) [0x105dd0916]
/Users/mal/.rbenv/versions/dev/bin/ruby(rb_ec_exec_node+0x14d) [0x105c01aad]
/Users/mal/.rbenv/versions/dev/bin/ruby(ruby_run_node+0x57) [0x105c018f7]
/Users/mal/.rbenv/versions/dev/bin/ruby(main+0x71) [0x105b51141]
</code></pre>
Ruby master - Bug #17543 (Closed): Ractor isolation broken by `self` in shareable proc
https://bugs.ruby-lang.org/issues/17543
2021-01-15T07:39:58Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Discussing with <a class="user active user-mention" href="https://bugs.ruby-lang.org/users/8409">@MaxLap (Maxime Lapointe)</a> we realized that the <code>self</code> in a shareable proc is not properly isolated:</p>
<pre><code>class Foo
attr_accessor :x
def pr
Ractor.make_shareable(Proc.new { self })
end
end
f = Foo.new
f.x = [1, 2, 3]
Ractor.new(f.pr) { |pr| pr.call.x << :oops }
p f.x # => [1, 2, 3, :oops]
</code></pre>
<p>If the <code>self</code> refers to a shareable object then it's fine, but for non-shareable objects it has to be reset to <code>nil</code> or to a global shareable object that would have an instructive <code>inspect</code>.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Ractor</span><span class="o">::</span><span class="no">DETACHED_SELF</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="k">def</span> <span class="nf"><<</span> <span class="no">Ractor</span><span class="o">::</span><span class="no">DETACHED_SELF</span>
<span class="k">def</span> <span class="nf">inspect</span>
<span class="s1">'<#detached self>'</span>
<span class="k">end</span>
<span class="k">alias</span> <span class="nb">to_s</span> <span class="nb">inspect</span>
<span class="k">end</span>
<span class="no">Ractor</span><span class="o">::</span><span class="no">DETACHED_SELF</span><span class="p">.</span><span class="nf">freeze</span>
</code></pre>
Ruby master - Bug #17531 (Closed): `did_you_mean` not Ractor friendly
https://bugs.ruby-lang.org/issues/17531
2021-01-12T19:30:56Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The gem <code>did_you_mean</code> uses a class instance variable that does not work with Ractor.</p>
<pre><code>$ RUBYOPT='--disable-did_you_mean' ruby -W0 -e 'Ractor.new{ begin ; nil + 42; rescue Exception => e; e.to_s end}.take'
# => prints nothing (ok)
$ ruby -W0 -e 'Ractor.new{ begin ; nil + 42; rescue Exception => e; e.to_s end}.take'
# Prints
/Users/mal/.rbenv/versions/3.0.0/lib/ruby/3.0.0/did_you_mean.rb:102:in `formatter'
/Users/mal/.rbenv/versions/3.0.0/lib/ruby/3.0.0/did_you_mean/core_ext/name_error.rb:9:in `to_s'
-e:1:in `rescue in block in <main>'
-e:1:in `block in <main>'
# (not ok)
</code></pre>
Ruby master - Bug #17497 (Closed): Ractor performance issue
https://bugs.ruby-lang.org/issues/17497
2020-12-31T21:48:50Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>There's a strange performance issue with Ractor (at least on MacOS, didn't run on other OS).</p>
<p>I ran a benchmark doing 3 different types of work:</p>
<ul>
<li>"fib": method calls (naive fibonacci calculation)</li>
<li>"cpu": <code>(0...1000).inject(:+)</code>
</li>
<li>"sleep": call <code>sleep</code>
</li>
</ul>
<p>I get the kind of results I was excepting for the <code>fib</code> and for sleeping, but the results for the "cpu" workload show a problem.</p>
<p>It is so slow that my pure Ruby backport (using Threads) is 65x faster 😮 on my Mac Pro (despite having 6 cores). Expected results would be 6x slower, so in that case Ractor is 400x slower than it should 😿</p>
<p>On my MacBook (2 cores) the results are not as bad, the <code>cpu</code> workload is 3x faster with my pure-Ruby backport (only) instead of ~2x slower, so the factor is 6x too slow.</p>
<pre><code>$ gem install backports
Successfully installed backports-3.20.0
1 gem installed
$ ruby ractor_test.rb
<internal:ractor>:267: warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.
fib: 110 ms | cpu: 22900 ms | sleep: 206 ms
$ B=t ruby ractor_test.rb
Using pure Ruby implementation
fib: 652 ms | cpu: 337 ms | sleep: 209 ms
</code></pre>
<p>Notice the <code>sleep</code> run takes similar time, which is good, and <code>fib</code> is ~6x faster on my 6-core CPU (and ~2x faster on my 2-core MacBook), again that's good as the pure ruby version uses Threads and thus runs with a single GVL.</p>
<p>The <code>cpu</code> version is the problem.</p>
<p>Script is here: <a href="https://gist.github.com/marcandre/bfed626e538a3d0fc7cad38dc026cf0e" class="external">https://gist.github.com/marcandre/bfed626e538a3d0fc7cad38dc026cf0e</a></p>
Ruby master - Bug #17428 (Closed): Method#inspect bad output for class methods
https://bugs.ruby-lang.org/issues/17428
2020-12-23T00:35:55Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code>$ $ ruby -e 'p String.method(:prepend)'
# 2.7.0:
#<Method: String.prepend(*)>
# 3.0.0:
#<Method: #<Class:Object>(Module)#prepend(*)>
</code></pre>
<p>@jeremyevans found it shows the method as pertaining to one level too high (which is good for objects as we don't want to show the singleton class there, but not for classes).</p>
<p>Probably due to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: What should be the correct output for Method#inspect with singleton methods? (Closed)" href="https://bugs.ruby-lang.org/issues/15608">#15608</a></p>
Ruby master - Bug #17379 (Closed): Refinement with modules redefinition bug
https://bugs.ruby-lang.org/issues/17379
2020-12-09T04:21:11Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Depending on the circumstance, a refinement can be modified even after being used:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">foo</span>
<span class="p">[</span><span class="ss">:base</span><span class="p">]</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">M</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="k">super</span> <span class="o"><<</span> <span class="ss">:M</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">Ext</span>
<span class="n">refine</span> <span class="no">Object</span> <span class="k">do</span>
<span class="kp">include</span> <span class="no">M</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">using</span> <span class="no">Ext</span>
<span class="nb">p</span> <span class="s1">'asd'</span><span class="p">.</span><span class="nf">foo</span> <span class="k">unless</span> <span class="no">ENV</span><span class="p">[</span><span class="s1">'SKIP'</span><span class="p">]</span> <span class="c1"># => [:base, :M] (ok)</span>
<span class="k">module</span> <span class="nn">M</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="k">super</span> <span class="o"><<</span> <span class="ss">:new_ref</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">p</span> <span class="s1">'asd'</span><span class="p">.</span><span class="nf">foo</span> <span class="c1"># => depends (not ok)</span>
</code></pre>
<p>Running this gives:</p>
<pre><code>$ ruby refinement.rb
[:base, :M]
[:base, :M] # => ok
$ SKIP=t ruby refinement.rb
[:base, :new_ref] # => should be [:base, :M]
</code></pre>
Ruby master - Bug #17374 (Rejected): Refined methods aren't visible from a refinement's module
https://bugs.ruby-lang.org/issues/17374
2020-12-07T05:25:04Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
Ruby master - Bug #17368 (Closed): `Ractor.select()` loops forever
https://bugs.ruby-lang.org/issues/17368
2020-12-05T07:41:44Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I propose it raises an error in <a href="https://github.com/ruby/ruby/pull/3848" class="external">https://github.com/ruby/ruby/pull/3848</a></p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span> <span class="c1"># => loops</span>
<span class="c1"># after</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">select</span> <span class="c1"># => ArgumentError, "specify at least one ractor or `yield_value`"</span>
</code></pre>
Ruby master - Bug #17366 (Closed): Ractor odd issue with timeout + receive + sleep + take
https://bugs.ruby-lang.org/issues/17366
2020-12-05T06:58:11Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I believe the following behavior is incorrect:</p>
<pre><code>ruby -r timeout -e 'r = Ractor.new { Timeout.timeout(0.1) { sleep(1) } rescue :timeout }; p r.take'
# => :timeout (ok)
ruby -r timeout -e 'r = Ractor.new { Timeout.timeout(0.1) { sleep(1) } rescue :timeout }; sleep(0.2); p r.take'
# => :timeout (ok)
ruby -r timeout -e 'r = Ractor.new { Timeout.timeout(0.1) { Ractor.receive } rescue :timeout }; p r.take'
# => :timeout (ok)
ruby -r timeout -e 'r = Ractor.new { Timeout.timeout(0.1) { Ractor.receive } rescue :timeout }; sleep(0.2); p r.take'
<internal:ractor>:130:in `take': The outgoing-port is already closed (Ractor::ClosedError) # => not ok
</code></pre>
Ruby master - Bug #17359 (Open): Ractor copy mode is not Ractor-safe
https://bugs.ruby-lang.org/issues/17359
2020-12-01T08:29:37Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>It should not be possible to mutate an object across Ractors, but the copy mode allows it currently:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="nb">attr_accessor</span> <span class="ss">:x</span>
<span class="k">def</span> <span class="nf">initialize_copy</span><span class="p">(</span><span class="o">*</span><span class="p">)</span>
<span class="vg">$last</span> <span class="o">=</span> <span class="nb">self</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span> <span class="o">=</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
<span class="n">o</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="mi">42</span>
<span class="n">r</span> <span class="o">=</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">o</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">copy</span><span class="o">|</span>
<span class="nb">puts</span> <span class="n">copy</span><span class="p">.</span><span class="nf">x</span> <span class="c1"># => 42</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="ss">:sync</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">yield</span> <span class="ss">:sync</span>
<span class="nb">puts</span> <span class="n">copy</span><span class="p">.</span><span class="nf">x</span> <span class="c1"># => 666</span>
<span class="k">end</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span> <span class="c1"># => :sync</span>
<span class="vg">$last</span><span class="p">.</span><span class="nf">x</span> <span class="o">=</span> <span class="mi">666</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span> <span class="c1"># => :sync</span>
<span class="n">r</span><span class="p">.</span><span class="nf">take</span>
</code></pre>
<p>Maybe the <code>copy</code> object should be marked as moved?</p>
Ruby master - Bug #17344 (Closed): `Ractor#shareable?` confused by recursive structures
https://bugs.ruby-lang.org/issues/17344
2020-11-26T09:46:49Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">y</span> <span class="o">=</span> <span class="p">[];</span> <span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="n">y</span><span class="p">,</span> <span class="p">{}].</span><span class="nf">freeze</span><span class="p">;</span> <span class="n">y</span> <span class="o"><<</span> <span class="n">x</span><span class="p">;</span> <span class="n">y</span><span class="p">.</span><span class="nf">freeze</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">shareable?</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="c1"># => false, ok, the `{}` is not frozen</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">shareable?</span><span class="p">(</span><span class="n">x</span><span class="p">)</span> <span class="c1"># => false, ok</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">shareable?</span><span class="p">(</span><span class="n">y</span><span class="p">)</span> <span class="c1"># => true, not ok!</span>
</code></pre>
<p>The error is that we can not mark anything as shareable until the whole tree has been searched successfully. Only when the full traversal is successful, then all visited objects can be marked as shareable. There might be a more clever way, but I couldn't think of one when working on my backport.</p>
Ruby master - Bug #17343 (Closed): Ractor can't clone frozen structures
https://bugs.ruby-lang.org/issues/17343
2020-11-26T09:44:49Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span><span class="p">([[]].</span><span class="nf">freeze</span><span class="p">)</span> <span class="p">{}</span> <span class="c1"># => FrozenError</span>
</code></pre>
<p>See <a href="https://github.com/ruby/ruby/pull/3817" class="external">https://github.com/ruby/ruby/pull/3817</a></p>
Ruby master - Bug #17310 (Closed): Closed ractors should die
https://bugs.ruby-lang.org/issues/17310
2020-11-08T03:17:25Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>While backporting Ractors, I found this issue:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mi">10</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="nb">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> <span class="p">}</span> <span class="p">}</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="nb">puts</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">count</span> <span class="c1"># => 1, ok</span>
<span class="c1"># but:</span>
<span class="mi">10</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="no">Ractor</span><span class="p">.</span><span class="nf">new</span> <span class="p">{</span> <span class="nb">sleep</span><span class="p">(</span><span class="mf">0.1</span><span class="p">)</span> <span class="p">}.</span><span class="nf">close</span> <span class="p">}</span>
<span class="nb">sleep</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="no">Ractor</span><span class="p">.</span><span class="nf">count</span> <span class="c1"># => 11, should be 1</span>
</code></pre>
Ruby master - Bug #17197 (Rejected): Some Hash methods still have arity 2 instead of 1
https://bugs.ruby-lang.org/issues/17197
2020-09-28T02:13:57Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p><code>Hash#each</code> was changed recently to have arity of 1.<br>
All other methods of <code>Hash</code> should behave the same.<br>
Much has been fixed since <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Enumerable & Hash yielding arity (Closed)" href="https://bugs.ruby-lang.org/issues/14015">#14015</a>, but some remains:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># Some methods consistently have arity 2:</span>
<span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}.</span><span class="nf">select</span><span class="p">(</span> <span class="o">&-></span><span class="p">(</span><span class="n">_kvp</span><span class="p">)</span> <span class="p">{}</span> <span class="p">)</span> <span class="c1"># => ArgumentError (wrong number of arguments (given 2, expected 1))</span>
</code></pre>
<p>All in all: <code>%i[select keep_if delete_if reject to_h]</code> have their arity still set at 2.</p>
Ruby master - Bug #17124 (Closed): Wrong "ambiguous first argument" warning
https://bugs.ruby-lang.org/issues/17124
2020-08-18T20:02:54Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code class="sh syntaxhl" data-language="sh"><span class="nv">$ </span>ruby <span class="nt">-v</span> <span class="nt">-e</span> <span class="s2">"x='a'; x.match? /[a-z]/"</span>
ruby 2.8.0dev <span class="o">(</span>2020-07-30T14:07:06Z master 352895b751<span class="o">)</span> <span class="o">[</span>x86_64-darwin18]
<span class="nt">-e</span>:1: warning: ambiguous first argument<span class="p">;</span> put parentheses or a space even after <span class="sb">`</span>/<span class="s1">' operator
</span></code></pre>
<p>There is no <code>/</code> operator in there and there is also no ambiguity as adding a space after the first <code>/</code> is a syntax error.</p>
<p>Is it possible to remove the warning altogether when the argument is lexed as a regexp?</p>
<p>The message could use a rewording too, maybe "ambiguous first argument; put parentheses around argument or add a space after `/' operator"</p>
Ruby master - Bug #16281 (Closed): `irb -w` issues warning
https://bugs.ruby-lang.org/issues/16281
2019-10-25T20:39:07Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code>$ irb -w
.rvm/rubies/ruby-head/lib/ruby/2.7.0/reline.rb:322: warning: instance variable @ambiguous_width not initialized
</code></pre>
<p>(Since f13db4adde532)</p>
Ruby master - Bug #15718 (Closed): YAML raises error when dumping strings with UTF32 encoding
https://bugs.ruby-lang.org/issues/15718
2019-03-20T20:21:55Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<pre><code class="shell syntaxhl" data-language="shell">ruby <span class="nt">-r</span> yaml <span class="nt">-e</span> <span class="s2">"p YAML.dump( ''.force_encoding('UTF-32LE') )"</span>
Traceback <span class="o">(</span>most recent call last<span class="o">)</span>:
4: from <span class="nt">-e</span>:1:in <span class="sb">`</span><main><span class="s1">'
3: from /Users/work/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/psych.rb:513:in `dump'</span>
2: from /Users/work/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/psych/visitors/yaml_tree.rb:118:in <span class="sb">`</span>push<span class="s1">'
1: from /Users/work/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/psych/visitors/yaml_tree.rb:136:in `accept'</span>
/Users/work/.rvm/rubies/ruby-2.6.1/lib/ruby/2.6.0/psych/visitors/yaml_tree.rb:298:in <span class="sb">`</span>visit_String<span class="s1">': incompatible encoding regexp match (US-ASCII regexp with UTF-32LE string) (Encoding::CompatibilityError)
</span></code></pre>
<p>Surprisingly, this works in Ruby 2.4.x, but not in 2.2, 2.3, 2.5 nor 2.6!</p>
Ruby master - Bug #15613 (Closed): Enumerator::Chain#each doesn't relay block signature
https://bugs.ruby-lang.org/issues/15613
2019-02-20T04:29:41Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently, the block given when iterating on the components of a <code>Enumerator::Chain</code> always have arity of -1 and <code>lambda?</code> is always <code>false</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Foo</span>
<span class="kp">include</span> <span class="no">Enumerable</span>
<span class="k">def</span> <span class="nf">each</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">to_enum</span> <span class="k">unless</span> <span class="n">block</span>
<span class="nb">p</span> <span class="n">block</span><span class="p">.</span><span class="nf">arity</span><span class="p">,</span> <span class="n">block</span><span class="p">.</span><span class="nf">lambda?</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">foo</span> <span class="o">=</span> <span class="no">Foo</span><span class="p">.</span><span class="nf">new</span>
<span class="n">foo</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&-></span><span class="p">{})</span> <span class="c1"># => 0, true</span>
<span class="n">foo</span><span class="p">.</span><span class="nf">each</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&-></span><span class="p">{})</span> <span class="c1"># => 0, true</span>
<span class="n">foo</span><span class="p">.</span><span class="nf">chain</span><span class="p">.</span><span class="nf">each</span><span class="p">(</span><span class="o">&-></span><span class="p">{})</span> <span class="c1"># => -1, false. Would ideally be 0, true</span>
</code></pre>
<p>It would be preferable if the block information wasn't lost.</p>
Ruby master - Bug #15376 (Closed): Default gems: how will it work exactly?
https://bugs.ruby-lang.org/issues/15376
2018-12-04T06:38:35Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Some standard libraries will be gemified in Ruby 2.6+.</p>
<ol>
<li>
<p>I believe we need to provide documentation for this. The NEWS file doesn't have much at all. The respective READMEs also have no relevant information and are misleading (see <a href="https://github.com/ruby/ostruct/pull/6" class="external">https://github.com/ruby/ostruct/pull/6</a>). I'll be glad to write an initial draft if need be, with the answers to the following questions...</p>
</li>
<li>
<p>Can we play with this right now? Maybe publishing prelease versions of these libraries?</p>
</li>
<li>
<p>Has this been tested with <code>Gemfile</code> and <code>gemspec</code>, i.e. it will be possible to add a specification for one of these?</p>
</li>
<li>
<p>What is supposed to happen if one does <code>gem install ostruct</code> in Ruby 2.5 (with current bundler, and with future bundler)?</p>
</li>
<li>
<p>Will it be possible to use these in <code>Gemfile</code>s even with older Ruby (but recent <code>bundler</code>), so one could say <code>gem 'ostruct'</code> in a Gemfile and run <code>bundle install</code> in Ruby 2.5 without things exploding?</p>
</li>
<li>
<p>Depending on 4/5, shouldn't we specify a <code> required_rubygems_version</code> and/or <code> required_ruby_version</code> in the gemspecs?</p>
</li>
</ol>
Ruby master - Bug #15078 (Closed): Hash splat of empty hash should not create a positional argument.
https://bugs.ruby-lang.org/issues/15078
2018-09-05T16:22:45Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Looks like <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Splat with empty keyword args gives unexpected results (Closed)" href="https://bugs.ruby-lang.org/issues/10856">#10856</a> is not completely fixed, but I can't reopen it</p>
<pre><code>def foo(*args); args; end
foo(**{}) # => []
foo(**Hash.new) # => [{}], should be []
</code></pre>
Ruby master - Bug #14674 (Closed): New mismatched indentations warnings?
https://bugs.ruby-lang.org/issues/14674
2018-04-10T17:43:28Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I recently got a failure in my test suite because ruby head warns of indentation it considers mismatched:</p>
<pre><code>$ ruby -w -e "
case
when :foo
end
"
-e:3: warning: mismatched indentations at 'when' with 'case' at 2
</code></pre>
<p>I hope this is not intentional and will be fixed.</p>
Ruby master - Bug #14201 (Closed): Regression due to over optimization of hash splat
https://bugs.ruby-lang.org/issues/14201
2017-12-18T20:27:47Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The following doesn't print anything nor raise anything in 2.5.0-rc1 or trunk:</p>
<pre><code>$ ruby -e "{**puts('hello')}; 42"
</code></pre>
<p>It should be the same as in Ruby 2.0-2.4:</p>
<pre><code>hello
-e:1:in `<main>': no implicit conversion of nil into Hash (TypeError)
</code></pre>
<p>Note: If you try to use the hash (e.g. passing as argument, storing in variable), then the correct behavior takes place. Found this bug through DeepCover's test suite.</p>
Ruby master - Bug #14057 (Closed): TracePoint#enable and disable should not yield arguments
https://bugs.ruby-lang.org/issues/14057
2017-10-26T06:54:53Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>While working on RubySpecs with Atul Bhosale, we discovered that <code>TracePoint#enable</code> and <code>#disable</code> yield <code>nil</code> instead of not yielding any argument.</p>
<p>This is mostly harmless as we usually use blocks, but it could create issues for lambdas/methods, for example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">def</span> <span class="nf">handle_trace</span><span class="p">;</span> <span class="k">end</span>
<span class="no">TracePoint</span><span class="p">.</span><span class="nf">new</span><span class="p">{}.</span><span class="nf">enable</span><span class="p">(</span><span class="o">&</span><span class="nb">method</span><span class="p">(</span><span class="ss">:handle_trace</span><span class="p">))</span> <span class="c1"># => ArgumentError: wrong number of arguments (given 1, expected 0)</span>
</code></pre>
<p>I'm fixing in trunk, would be nice to backport.</p>
Ruby master - Bug #14015 (Closed): Enumerable & Hash yielding arity
https://bugs.ruby-lang.org/issues/14015
2017-10-14T20:19:18Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The subtle difference between <code>yield 1, 2</code> and <code>yield [1, 2]</code> has always confused me.</p>
<p>Today I wanted to pass a method to Hash#flat_map and realized how it's even more confusing than I thought.</p>
<p>I assumed that <code>Hash#each</code> was calling <code>yield key, value</code>. But somehow it's not that simple:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}.</span><span class="nf">map</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">){})</span> <span class="c1"># => [nil]</span>
<span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}.</span><span class="nf">flat_map</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">){})</span> <span class="c1">#=> ArgumentError: wrong number of arguments (given 1, expected 2)</span>
</code></pre>
<p>What blows my mind, is that a custom method <code>each</code> that does <code>yield a, 1</code> has different result!</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="o"><<</span> <span class="n">o</span> <span class="o">=</span> <span class="no">Object</span><span class="p">.</span><span class="nf">new</span>
<span class="kp">include</span> <span class="no">Enumerable</span>
<span class="k">def</span> <span class="nf">each</span>
<span class="k">yield</span> <span class="ss">:a</span><span class="p">,</span> <span class="mi">1</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">o</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">){})</span> <span class="c1"># => [nil]</span>
<span class="n">o</span><span class="p">.</span><span class="nf">flat_map</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">key</span><span class="p">,</span> <span class="n">value</span><span class="p">){})</span> <span class="c1"># => [nil] does not raise!!</span>
</code></pre>
<p>I don't even know how that's possible, since Hash doesn't have a specialized <code>flat_map</code> method...</p>
<p>Here's a list of methods that accept a lambda of arity 2 (as I would expect)<br>
For Hash<br>
each, any?, map, select, reject,<br>
For a custom yield<br>
each, any?, map, count, find_index, flat_map, all?, one?, none?, take_while, uniq</p>
<p>These two lists have <code>each</code>, <code>map</code> and <code>any?</code> in common. Others work in one flavor, not the other. Many require arity 1: find, sort_by, grep, grep_v, count, detect, find_index, find_all, ...</p>
<p>To make things even more impossible, <code>Hash#map</code> has been working with arity 2 since Ruby 2.4 only.</p>
<p>Finally, <code>Hash#each</code> changes the expected arity of <code>select</code>, <code>reject</code>, and <code>any?</code>, but not of <code>map</code>:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"> <span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}</span> <span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">){})</span> <span class="c1"># => {}</span>
<span class="p">{</span><span class="ss">a: </span><span class="mi">1</span><span class="p">}.</span><span class="nf">each</span><span class="p">.</span><span class="nf">select</span><span class="p">(</span><span class="o">&-></span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">){})</span> <span class="c1"># => wrong number of arguments (given 1, expected 2)</span>
</code></pre>
<p>Conclusion:</p>
<p>It seems more or less impossible to guess the expected arity of methods of Enumerable and of Hash, and they are not even consistent with one another. This makes these methods more or less unusable with lambdas.</p>
<p>While compatibility could be an issue, the fact that <code>Hash#map</code> has changed it's arity (I believe following <a href="https://bugs.ruby-lang.org/issues/13391" class="external">https://bugs.ruby-lang.org/issues/13391</a> ) makes me think that compatibility with the lesser used methods would be even less of a problem.</p>
<p>My personal wish: that the following methods be fixed to expect arity 2 for lambdas:</p>
<p>For both Hash & Enumerable:</p>
<ul>
<li>find, sort_by, grep, grep_v, detect, find_all, partition, group_by, min_by, max_by, minmax_by, reverse_each, drop_while, sum<br>
For Hash:</li>
<li>count, find_index, flat_map, all?, one?, none?, take_while, uniq<br>
For Enumerable:</li>
<li>select, reject</li>
</ul>
<p>Matz, what do you think?</p>
Ruby master - Bug #13973 (Closed): super_method fails on some UnboundMethods
https://bugs.ruby-lang.org/issues/13973
2017-10-05T02:01:33Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p><code>super_method</code> fails to go up the ancestry chain for methods that are only defined in included modules:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">A</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">B</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">C</span>
<span class="kp">include</span> <span class="no">A</span>
<span class="kp">include</span> <span class="no">B</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">D</span>
<span class="k">def</span> <span class="nf">foo</span>
<span class="k">end</span>
<span class="kp">include</span> <span class="no">A</span>
<span class="kp">include</span> <span class="no">B</span>
<span class="k">end</span>
<span class="no">C</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">)</span> <span class="c1"># => #<UnboundMethod: C(B)#foo> (ok)</span>
<span class="no">C</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">super_method</span> <span class="c1"># => nil (wrong, should be <UnboundMethod: <something>(A)#foo>)</span>
<span class="no">C</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">super_method</span> <span class="c1"># => #<Method: Object(A)#foo> (ok)</span>
<span class="no">D</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">super_method</span> <span class="c1"># => #<UnboundMethod: Object(B)#foo> (ok)</span>
<span class="no">D</span><span class="p">.</span><span class="nf">instance_method</span><span class="p">(</span><span class="ss">:foo</span><span class="p">).</span><span class="nf">super_method</span><span class="p">.</span><span class="nf">super_method</span> <span class="c1"># => #<UnboundMethod: Object(A)#foo> (ok)</span>
</code></pre>
<p>Note that the results for C and D's super_method differ slightly, with one outputing "C(B)" and the other "Object(B)". I don't understand why "Object" shows anywhere in my example. I would have expected the output to be "D(B)" in the later case. Should I open a different issue for this?</p>
Ruby master - Bug #11776 (Closed): dig and custom objects
https://bugs.ruby-lang.org/issues/11776
2015-12-06T05:18:02Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Although currently undocumented and untested, it is possible to <code>dig</code> objects of any class that implements <code>dig</code>:</p>
<pre><code>class Foo
def dig(x, *)
40 + x
end
end
{hello: Foo.new}.dig(:hello, 2) # => 42
</code></pre>
<p>This seems actually quite nice to me.</p>
<p>Matz, could you confirm that this is part of the new feature? I'll fix the documentation and add some basic tests</p>
Ruby master - Bug #10831 (Closed): Variable keyword arguments shouldn't create immortal symbols
https://bugs.ruby-lang.org/issues/10831
2015-02-05T19:58:53Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Calling a method with keyword arguments will, sometimes, create immortal symbols.</p>
<p>The following tests should not fail:</p>
<pre><code>def test_kwarg_symbol_leak_no_rest
foo = -> (arg: 42) {}
assert_no_immortal_symbol_created("kwarg no rest") do |name|
assert_raise(ArgumentError) { foo.call(name.to_sym => 42) }
end
end
def test_kwarg_symbol_leak_with_rest
foo = -> (arg: 2, **options) {}
assert_no_immortal_symbol_created("kwarg with rest") do |name|
foo.call(name.to_sym => 42)
end
end
def test_kwarg_symbol_leak_just_rest
foo = -> (**options) {}
assert_no_immortal_symbol_created("kwarg just rest") do |name|
foo.call(name.to_sym => 42)
end
end
</code></pre>
<p>Note: the last one succeeds (because the hash is simply cloned internally), and is there for completeness.</p>
Ruby master - Bug #10828 (Closed): send should not create immortal symbols
https://bugs.ruby-lang.org/issues/10828
2015-02-04T19:01:50Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>While <code>public_send</code> is ok, <code>send</code> and <code>__send__</code> create immortal symbols when they shouldn't.</p>
Ruby master - Bug #9660 (Closed): test/unit, minitest & bundler
https://bugs.ruby-lang.org/issues/9660
2014-03-21T19:15:10Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>test/unit now calls <code>gem 'minitest'</code>, but this will create regressions for anyone using <code>bundler</code>.</p>
<p>For example, create an empty <code>Gemfile</code> and try <code>bundle exec ruby -e "require 'test/unit'"</code></p>
<p>You get an error:</p>
<pre><code>.rvm/gems/ruby-head@global/gems/bundler-1.5.3/lib/bundler/rubygems_integration.rb:240:in `block in replace_gem': minitest is not part of the bundle. Add it to Gemfile. (Gem::LoadError)
</code></pre>
<p>See: <a href="https://github.com/ruby/ruby/commit/da61291a25faae95f33de6756b2eaa4804d5ef2b#commitcomment-5761129" class="external">https://github.com/ruby/ruby/commit/da61291a25faae95f33de6756b2eaa4804d5ef2b#commitcomment-5761129</a></p>
Ruby master - Bug #9242 (Closed): Rdoc detection of aliases
https://bugs.ruby-lang.org/issues/9242
2013-12-12T04:46:38Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The online doc appears to be making bad detection of aliases.</p>
<p>For example, Array#map and Array#collect are not marked as aliases (on either ruby-doc.org or docs.ruby-lang.org)</p>
<p>On the other hand, when aliases are detected, the generated method interface and the name of the method it is aliases to are always the same for both methods.</p>
<p>For example, the doc for Array#find_index says it is an alias to find_index and has interface showing index (again on both sites), e.g. <a href="http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-find_index" class="external">http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-find_index</a></p>
<p>It might also be a good idea to always have doc examples using both forms in case of aliases.</p>
Ruby master - Bug #9048 (Closed): Remove legacy ±(binary) special cases.
https://bugs.ruby-lang.org/issues/9048
2013-10-24T00:30:13Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Is there any reason not to get rid of the following special cases?</p>
<pre><code>'+(binary)'.to_sym # => :+ when expected :"+(binary)"
</code></pre>
<p>The following patch didn't reveal any failure in make test:</p>
<p>diff --git a/parse.y b/parse.y<br>
index 76fc9e7..6550235 100644<br>
--- a/parse.y<br>
+++ b/parse.y<br>
@@ -10045,8 +10045,6 @@ static const struct {<br>
} op_tbl[] = {<br>
{tDOT2, ".."},<br>
{tDOT3, "..."},</p>
<ul>
<li>{'+', "+(binary)"},</li>
<li>{'-', "-(binary)"},<br>
{tPOW, "<strong>"},<br>
{tDSTAR, "</strong>"},<br>
{tUPLUS, "+@"},<br>
diff --git a/test/ruby/test_m17n.rb b/test/ruby/test_m17n.rb<br>
index 7c37c8a..3ea346f 100644<br>
--- a/test/ruby/test_m17n.rb<br>
+++ b/test/ruby/test_m17n.rb<br>
@@ -1230,7 +1230,7 @@ class TestM17N < Test::Unit::TestCase</li>
</ul>
<p>def test_symbol_op<br>
ops = %w"</p>
<ul>
<li>
<pre><code> .. ... + - +(binary) -(binary) * / % ** +@ -@ | ^ & ! <=> > >= < <= ==
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> .. ... + - * / % ** +@ -@ | ^ & ! <=> > >= < <= ==
=== != =~ !~ ~ ! [] []= << >> :: `
</code></pre>
"<br>
ops.each do |op|</li>
</ul>
Ruby master - Bug #8841 (Closed): Module#included_modules and prepended modules
https://bugs.ruby-lang.org/issues/8841
2013-08-31T08:17:39Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The documentation for Module#included_modules currently states "Returns the list of modules included in +mod+."</p>
<p>This was never perfectly accurate, as the list also contains modules included in +mod+'s ancestors.</p>
<p>It now also includes prepended modules.</p>
<p>This is consistent with <code>include?</code> that returns true for prepended modules, but not quite consistent with <code>included</code> that does not get called for prepended modules.</p>
<p>Matz, could you confirm that current behavior is what you want?</p>
<p>If so, we should fix the documentation of <code>include?</code> and <code>included_modules</code>.</p>
Ruby master - Bug #7916 (Closed): Callback Module.used is not used...
https://bugs.ruby-lang.org/issues/7916
2013-02-23T08:08:28Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Module.used was meant to be called when it is called with <code>using</code>, see r36596.</p>
<p>It's not called right now.</p>
Ruby master - Bug #7780 (Closed): Marshal & YAML should deserialize only basic types by default.
https://bugs.ruby-lang.org/issues/7780
2013-02-04T11:30:48Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>YAML is a wonderful, powerful and expressive format to serialize data in a human readable way.</p>
<p>It can be used, for example, to read and write nice configuration files, to store strings, numbers, dates & times in a hash.</p>
<p>YAML.load will, by default, instantiate any user class and set instance variables directly.</p>
<p>On the other hand, this can make apparently innocent code lead to major vulnerabilities, as was clearly illustrated by different exploits recently.</p>
<p>I feel YAML.load should, by default, be safe to use, for example by instantiating only known core classes.</p>
<p>The same can be said for Marshal, even though it would more rarely be used as a public interface to exchange data.</p>
<p>Maybe the following transition path could be taken:</p>
<ol>
<li>Have {YAML|Marshal}.load issue a warning (once) that next minor will only deserialize basic types.</li>
<li>Create {YAML|Marshal}.unsafe_load, which does the same thing as current <code>load</code>, without a warning of course.<br>
As these changes are compatible and extremely minor, I would like them to be considered for Ruby 2.0.0. They also make for a</li>
</ol>
<p>"Secure by default" is not a new concept.<br>
Rails 3.0 has XSS protection by default, for example. The fact that one needs to do extra processing like calling <code>raw</code> when that security needs to be bypassed makes XSS attacks less likely.<br>
I believe the typical use of Yaml.load is to load basic types.<br>
We should expect users to use the easiest solution, so that should be the safe way.<br>
If a tool makes the safe way of doing things the default, and makes it easy to do more complex deserializing (e.g. whitelisting some user classes), this can only lead to less vulnerabilities.</p>
<p>I hope nobody will take offence that I've tagged this issue as a "bug". The current behavior is as speced, but it can be argued that a design that is inherently insecure is a defect.</p>
Ruby master - Bug #7765 (Closed): Proc#arity bug with optional argument
https://bugs.ruby-lang.org/issues/7765
2013-02-01T05:38:17Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>We have:</p>
<pre><code>Proc.new{|a, b, c, d, e|}.arity # => 5
</code></pre>
<p>Matz decided <a href="/issues/5694">[ruby-core:46515]</a> we also have:</p>
<pre><code>Proc.new{|a, b, c, d, e=0|}.arity # => 4
</code></pre>
<p>It looks like we currently have:</p>
<pre><code>Proc.new{|a, b=0, c, d, e|}.arity # => 1, should be same as above
</code></pre>
<p>Hopefully there won't be disagreement that this is a bug?</p>
<p>I'm asking in particular because there was a specific test committed by Yui to that effect. I hope this was just an oversight?</p>
<pre><code>assert_equal(0, proc{|x=0, y|}.arity) # Should be 1, not 0. test/ruby/test_proc.rb:67
</code></pre>
<p>My patch is ready and I will commit it unless there is objection.</p>
<p><a href="https://github.com/marcandre/ruby/compare/marcandre:trunk...marcandre:proc_curry" class="external">https://github.com/marcandre/ruby/compare/marcandre:trunk...marcandre:proc_curry</a></p>
Ruby master - Bug #7755 (Closed): JSON::Generate#configure's argument conversion
https://bugs.ruby-lang.org/issues/7755
2013-01-30T04:33:38Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I notice a tiny bug in ext/json/generator/generator.c:514</p>
<pre><code>tmp = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h");
if (NIL_P(tmp)) {
rb_raise(rb_eArgError, "opts has to be hash like or convertable into a hash");
}
opts = tmp;
</code></pre>
<p>Bug is that rb_convert_type never returns nil.</p>
<p>Either both rb_convert_type are changed to rb_check_convert_type, or these lines are simply replaced by:</p>
<pre><code>opts = rb_convert_type(opts, T_HASH, "Hash", "to_hash");
</code></pre>
<p>I'd recommend this last option, for consistency with the rest of MRI.</p>
Ruby master - Bug #7728 (Closed): Range#bsearch on other Numerics?
https://bugs.ruby-lang.org/issues/7728
2013-01-23T03:12:30Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Range#bsearch attempts to do something on generic Numeric classes.</p>
<p>I feel it is both useless and buggy:</p>
<pre><code>(Rational(-1,2)..Rational(9,4)).bsearch{|x| true} # => yields with 7/8 and 33/16
(Rational(-1,2)..Rational(9,4)).bsearch{|x| false} # => loops forever
(BigDecimal('0.5')..BigDecimal('2.25'))... # => same
</code></pre>
<p>I feel the current implementation (aside from the bugs) only makes sense on Integers.</p>
<p>Possible approaches:</p>
<ul>
<li>Rational</li>
</ul>
<ol>
<li>convert to float, or</li>
<li>bsearch accepts a "max iterations" parameter (which would be required for Rational), or</li>
<li>forbid altogether</li>
</ol>
<ul>
<li>BigDecimal</li>
</ul>
<ol>
<li>convert to float, or</li>
<li>look at the space of decimal numbers in the range without a higher precision than begin or end.</li>
</ol>
<p>Given the timeframe though, I recommend we raise a TypeError for both in 2.0.0 (or a NotImplemented if we decide what should be done).</p>
Ruby master - Bug #7726 (Closed): bsearch should handle block result in a consistent way
https://bugs.ruby-lang.org/issues/7726
2013-01-22T18:52:35Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The documentation states that the block of bsearch must<br>
return either true/false or a number.</p>
<p>If the block returns another object (other than nil), I feel that either</p>
<ol>
<li>It should be considered as 'truthy'</li>
<li>It should raise a TypeError</li>
</ol>
<p>Currently it does not raise an error and returns a result different than if <code>true</code> was passed:</p>
<p>(1..3).bsearch{ 'x' } == (1..3).bsearch{ true } # => false</p>
Ruby master - Bug #7725 (Closed): bsearch should return enumerator when called without a block
https://bugs.ruby-lang.org/issues/7725
2013-01-22T18:48:44Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>bsearch should return enumerator when called without a block</p>
<p>This would allow, for example</p>
<p>values.bsearch.with_index{|val, index| val >= some_array[index]} # => a value</p>
<p>Otherwise, one must use zip/each_with_index and will get an array returned, not just the value seeked:</p>
<p>r = values.zip(some_array).bsearch{|val, other_val| val >= other_val}<br>
a_value = r.first</p>
Ruby master - Bug #7724 (Closed): 6 bugs with Range#bsearch over floats
https://bugs.ruby-lang.org/issues/7724
2013-01-22T18:47:35Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Take the following code, with from, to and search all Integer or all Float:</p>
<p>(from...to).bsearch{|f| f >= search}</p>
<p>I expected it to:<br>
0) never yield and return nil if range is empty, i.e. from >= to ("trivial test")</p>
<ol>
<li>never yield more than 65 times for floats<br>
or Math.log(to-from, 2)+1 for Integer ("log test")</li>
<li>return search if from <= search < to, nil otherwise ("coverage test")</li>
<li>never yield the same <code>f</code> ("uniqueness test")</li>
<li>if range is exclusive, never yield <code>to</code> nor return <code>to</code>; if range is inclusive and block returns false always yield <code>to</code> ("end of range test")</li>
<li>never yield a number < from or > to ("out of range test")</li>
</ol>
<p>These conditions are all respected for Integers but all can be broken for Floats<br>
Test 0, 1, 3, 4 & 5 fail even for small ordinary float values, while test 2 requires some larger floats, say 1e100 to fail.<br>
For example bsearch can yield over 2000 times (instead of at most 65).</p>
<p>These tests and a correct Ruby implementation of bsearch can be found here: <a href="https://github.com/marcandre/backports/compare/marcandre:master...marcandre:bsearch" class="external">https://github.com/marcandre/backports/compare/marcandre:master...marcandre:bsearch</a><br>
My implementation also passes the MRI tests.</p>
Ruby master - Bug #7715 (Closed): Lazy enumerators should want to stay lazy.
https://bugs.ruby-lang.org/issues/7715
2013-01-19T02:33:26Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I'm just waking up to the fact that many methods turn a lazy enumerator in a non-lazy one.</p>
<p>Here's an example from Benoit Daloze in <a href="/issues/6261">[ruby-core:44151]</a>:</p>
<p>lines = File.foreach('a_very_large_file').lazy<br>
.select {|line| line.length < 10 }<br>
.map {|line| line.chomp!; line }<br>
.each_slice(3)<br>
.map {|lines| lines.join(';').downcase }<br>
.take_while {|line| line.length > 20 }</p>
<p>That code will produce the right result but <em>will read the whole file</em>, which is not what is desired</p>
<p>Indeed, <code>each_slice</code> currently does not return a lazy enumerator :-(</p>
<p>To make the above code as intended, one must call <code>.lazy</code> right after the <code>each_slice(3)</code>. I feel this is dangerous and counter intuitive.</p>
<p>Is there a valid reason for this behavior? Otherwise, I would like us to consider returning a lazy enumerator for the following methods:<br>
(when called without a block)<br>
each_with_object<br>
each_with_index<br>
each_slice<br>
each_entry<br>
each_cons<br>
(always)<br>
chunk<br>
slice_before</p>
<p>The arguments are:</p>
<ul>
<li>fail early (much easier to realize one needs to call a final <code>force</code>, <code>to_a</code> or <code>each</code> than realizing that a lazy enumerator chain isn't actually lazy)</li>
<li>easier to remember (every method normally returning an enumerator returns a lazy enumerator). basically this makes Lazy covariant</li>
<li>I'd expect that if you get lazy at some point, you typically want to remain lazy until the very end</li>
</ul>
Ruby master - Bug #7706 (Closed): Lazy#zip should not call `lazy`
https://bugs.ruby-lang.org/issues/7706
2013-01-17T03:27:36Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Current implementation of Lazy#zip has problems:</p>
<ol>
<li>
<p>calls <code>lazy</code> when this is not excepted, necessary nor documented. Any reason to not call <code>each</code> instead?</p>
</li>
<li>
<p>calls <code>lazy</code> without checking previously for type:</p>
<p>[1].lazy.zip(42) # =>NoMethodError: undefined method `lazy' for 42:Fixnum</p>
<a name="expected-same-as-1zip42-ie-a-TypeError"></a>
<h1 >expected same as [1].zip(42), i.e. a TypeError<a href="#expected-same-as-1zip42-ie-a-TypeError" class="wiki-anchor">¶</a></h1>
</li>
<li>
<p>inefficient in the case where all arguments are arrays</p>
</li>
</ol>
<p>I'll address these when I get a chance. I don't understand why <code>lazy</code> is called instead of <code>each</code> though. Anyone?</p>
Ruby master - Bug #7696 (Closed): Lazy enumerators with state can't be rewound
https://bugs.ruby-lang.org/issues/7696
2013-01-15T06:45:46Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The 4 lazy enumerators requiring internal state, i.e. {take|drop}{_while}, don't work as expected after a couple <code>next</code> and a call to <code>rewind</code>.</p>
<p>For example:</p>
<pre><code>e=(1..42).lazy.take(2)
e.next # => 1
e.next # => 2
e.rewind
e.next # => 1
e.next # => StopIteration: iteration reached an end, expected 2
</code></pre>
<p>This is related to <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: 3 bugs with Lazy enumerators with state (Closed)" href="https://bugs.ruby-lang.org/issues/7691">#7691</a>; the current API does not give an easy way to handle state.</p>
<p>Either there's a dedicated callback to rewind, or data must be attached to the yielder.</p>
Ruby master - Bug #7692 (Closed): Enumerator::Lazy#drop_while and take_while should require a block.
https://bugs.ruby-lang.org/issues/7692
2013-01-14T16:33:07Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Enumerator::Lazy#drop_while and take_while should require a block.</p>
<p>Currently:</p>
<pre><code>[1].lazy.drop_while.force # => LocalJumpError: no block given
[1].lazy.take_while.force # => LocalJumpError: no block given
</code></pre>
<p>After patch, these will raise an ArgumentError "tried to call lazy drop_while without a block"</p>
Ruby master - Bug #7690 (Closed): Enumerable::Lazy#flat_map should not call each
https://bugs.ruby-lang.org/issues/7690
2013-01-13T11:30:38Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I would expect that</p>
<pre><code>array.flat_map{...} == array.lazy.flat_map{...}.force
</code></pre>
<p>This is not always the case:</p>
<pre><code>[1].flat_map{|i| {i => i} } # => [{1 => 1}], ok
[1].lazy.flat_map{|i| {i => i} }.force # => [[1, 1]], expected [{1 => 1}]
</code></pre>
<p>Note that Matz confirmed that it is acceptable to return straight objects instead of arrays for flat_map <a href="/issues/6155">[ruby-core:43365]</a></p>
<p>It looks like this was intended for nested lazy enumerators:</p>
<pre><code>[1].lazy.flat_map{|i| [i].lazy }.force # => [1]
</code></pre>
<p>I don't think that's the correct result, and it is different from a straight flat_map:</p>
<pre><code>[1].flat_map{|i| [i].lazy } # => [#<Enumerator::Lazy: [1]>]
</code></pre>
<p>This is caused by Lazy#flat_map calls each (while Enumerable#flat_map only looks for Arrays/object responding to to_ary).</p>
Ruby master - Bug #7248 (Closed): Shouldn't Enumerator::Lazy.new be private?
https://bugs.ruby-lang.org/issues/7248
2012-10-31T13:23:13Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Is there a reason why Enumerator::Lazy.new is not private?</p>
<p>Lazy enumerators should be created with <code>Enumerable#lazy</code>. Moreover, there is no doc, and it can give unexpected results too.</p>
Ruby master - Bug #6538 (Rejected): Mutability of Rational and Complex
https://bugs.ruby-lang.org/issues/6538
2012-06-03T07:20:46Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>I hesitated to report this, but there is a "hole" in the immutability of Rational & Complex:</p>
<pre><code>r = Rational(0) # Rationals are immutable
r.freeze # but let's be certain and freeze it!
magic_trick(r) # r is now changed:
r # => (1/42)
</code></pre>
<p>The same thing occurs with Complex. I've left out the definition of <code>magic_trick</code> for anyone who wants to try and figure it out, but it's here: <a href="http://pastie.org/4016117" class="external">http://pastie.org/4016117</a></p>
<p>Is this worth fixing?</p>
Ruby master - Bug #6120 (Closed): Float and BigDecimal bug in remainder in corner cases
https://bugs.ruby-lang.org/issues/6120
2012-03-07T14:51:41Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently:</p>
<pre><code>4.2.remainder(+Float::INFINITY) # => 4.2, ok
4.2.remainder(-Float::INFINITY) # => NaN, should be 4.2
# (same with all signs reversed)
</code></pre>
<p>Reasons the remainder should be 4.2 and not NaN:</p>
<ol>
<li>foo.remainder(bar) == foo.remainder(-bar)</li>
<li>foo.remainder(bar) == foo when bar.abs > foo.abs</li>
</ol>
<p>Similarly:<br>
require 'bigdecimal'<br>
bd = BigDecimal.new("4.2")<br>
bd.remainder(BigDecimal.new("+Infinity")) # => NaN, should be bd<br>
bd.remainder(BigDecimal.new("-Infinity")) # => NaN, should be bd<br>
# (same with all signs reverse)</p>
<p>Reasons: same as float.</p>
<p>Finally:<br>
bd = BigDecimal.new("4.2")<br>
bd.modulo(BigDecimal.new("0")) # => ZeroDivisionError, probably ok?<br>
bd.remainder(BigDecimal.new("0")) # => NaN, should be probably raise a ZeroDivisionError?</p>
<p>Like in <a class="issue tracker-4 status-5 priority-4 priority-default closed" title="Backport: Float#% bug in cornercases (Closed)" href="https://bugs.ruby-lang.org/issues/6044">#6044</a>, this could be decided either way, as long as there is consistency. Anyone prefer NaN to raising a ZeroDivisionError?</p>
Ruby master - Bug #6087 (Closed): How should inherited methods deal with return values of their o...
https://bugs.ruby-lang.org/issues/6087
2012-02-26T06:02:37Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Just noticed that we still don't have a consistent way to handle return values:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span> <span class="o"><</span> <span class="no">Array</span>
<span class="k">end</span>
<span class="n">a</span> <span class="o">=</span> <span class="no">A</span><span class="p">.</span><span class="nf">new</span>
<span class="n">a</span><span class="p">.</span><span class="nf">flatten</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># => A</span>
<span class="n">a</span><span class="p">.</span><span class="nf">rotate</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># => Array</span>
<span class="p">(</span><span class="n">a</span> <span class="o">*</span> <span class="mi">2</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => A</span>
<span class="p">(</span><span class="n">a</span> <span class="o">+</span> <span class="n">a</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => Array</span>
</code></pre>
<p>Some methods are even inconsistent depending on their arguments:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">a</span><span class="p">.</span><span class="nf">slice!</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => A</span>
<span class="n">a</span><span class="p">.</span><span class="nf">slice!</span><span class="p">(</span><span class="mi">0</span><span class="o">..</span><span class="mi">0</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => A</span>
<span class="n">a</span><span class="p">.</span><span class="nf">slice!</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => Array</span>
<span class="n">a</span><span class="p">.</span><span class="nf">slice!</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => Array</span>
<span class="n">a</span><span class="p">.</span><span class="nf">slice!</span><span class="p">(</span><span class="mi">1</span><span class="o">..</span><span class="mi">0</span><span class="p">).</span><span class="nf">class</span> <span class="c1"># => Array</span>
</code></pre>
<p>Finally, there is currently no constructor nor hook called when making these new copies, so they are never properly constructed.</p>
<p>Imagine this simplified class that relies on <code>@foo</code> holding a hash:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">A</span> <span class="o"><</span> <span class="no">Array</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span>
<span class="k">super</span>
<span class="vi">@foo</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">initialize_copy</span><span class="p">(</span><span class="n">orig</span><span class="p">)</span>
<span class="k">super</span>
<span class="vi">@foo</span> <span class="o">=</span> <span class="vi">@foo</span><span class="p">.</span><span class="nf">dup</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">a</span> <span class="o">=</span> <span class="no">A</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">flatten</span>
<span class="n">a</span><span class="p">.</span><span class="nf">class</span> <span class="c1"># => A</span>
<span class="n">a</span><span class="p">.</span><span class="nf">instance_variable_get</span><span class="p">(</span><span class="ss">:@foo</span><span class="p">)</span> <span class="c1"># => nil, should never happen</span>
</code></pre>
<p>I feel this violates object orientation.</p>
<p>One solution is to always return the base class (<code>Array</code>/<code>String</code>/...).</p>
<p>Another solution is to return the current subclass. To be object oriented, I feel we must do an actual <code>dup</code> of the object, including copying the instance variables, if any, and calling <code>initialize_copy</code>. Exceptions to this would be (1) explicit documentation, e.g. <code>Array#to_a</code>, or (2) methods inherited from a module (like <code>Enumerable</code> methods for <code>Array</code>).</p>
<p>I'll be glad to fix these once there is a decision made on which way to go.</p>
Ruby master - Bug #6086 (Rejected): Number of arguments and named parameters
https://bugs.ruby-lang.org/issues/6086
2012-02-25T16:30:57Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>While working on the messages of "wrong number of arguments" error (see <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Treatment of Wrong Number of Arguments (Closed)" href="https://bugs.ruby-lang.org/issues/6085">#6085</a>), I realized that the new named parameter feature can lead to misleading error messages:</p>
<p>def foo(x: 42)<br>
end</p>
<p>arg = {x: :bar}<br>
foo(arg) # => nil (no error)<br>
arg = :bar<br>
foo(arg) # => ArgumentError: wrong number of arguments (1 for 0)</p>
<p>It would be better if the wording was changed for methods accepting options. Maybe something like:</p>
<p>foo(arg) # => ArgumentError: wrong number of arguments (1 for 0 **)</p>
<p>Suggestions?</p>
Ruby master - Bug #6085 (Closed): Treatment of Wrong Number of Arguments
https://bugs.ruby-lang.org/issues/6085
2012-02-25T15:47:19Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>For brevity, let me abbreviate:</p>
<pre><code>WNA = "wrong number of arguments"
</code></pre>
<p>Ruby could provide more accurate information when raising an ArgumentError for WNA.</p>
<p>Example:</p>
<p>def foo(a, b=42); end<br>
foo # => WNA (0 for 1)<br>
for(1,2,3) # => WNA (3 for 2)</p>
<p>It would be strictly superior if the message said instead "WNA (0 for 1..2)" and "WNA (3 for 1..2)":</p>
<ul>
<li>
<p>more useful as it gives more information at a glance</p>
</li>
<li>
<p>consistent with calling builtin methods:</p>
<p>"".index # => WNA (0 for 1..2)<br>
"".index(1,2,3) # => WNA (3 for 1..2)</p>
</li>
</ul>
<p>Ruby is also not always consistent in its wording when there is a *rest argument:</p>
<p>Enumerator.new # => WNA (0 for 1+)<br>
[].insert # => WNA (at least 1)</p>
<p>File.chown # => WNA (0 for 2+)<br>
Process.kill # => WNA (0 for at least 2)</p>
<p>While reviewing and factorizing all WNA errors, I also found a problematic case:</p>
<p>"".sub(//) # => WNA (1 for 1..2)</p>
<p>It would probably less confusing if it said (1 for 2), as the form without a block requires 2 parameters. Same applies to <code>sub!</code></p>
<p>Also, <code>Module#define_method</code> could say "WNA (3 for 1)" when it actually accepts only up to 2 arguments.</p>
<p>I've implemented two patches that address all these issues.</p>
<p>The first one improves the error message when calling user methods and lambdas.</p>
<p>The second harmonizes the builtin methods and fixes the few that need to be fixed.</p>
<p>The two commits can be found here:</p>
<p><a href="https://github.com/marcandre/ruby/commits/rb_arity_check" class="external">https://github.com/marcandre/ruby/commits/rb_arity_check</a></p>
<p>Complete list of changes:</p>
<ul>
<li>
<p>Improvements:</p>
<p>"".sub(//): WNA (1 for 1..2) => WNA (1 for 2)<br>
(same with sub)<br>
Module#define_method: WNA (3 for 1) => WNA (3 for 1..2)<br>
exec: WNA => WNA (0 for 1+)<br>
Hash.new(1){}: WNA => WNA (1 for 0)<br>
instance_eval("", "", 1, 2)<br>
WNA instance_eval(...) or instance_eval{...}<br>
=> WNA (4 for 1..3)<br>
(same with module_eval and class_eval)<br>
Module#mix: WNA (4 for 1) => WNA (4 for 1..3)<br>
Module#mix, with incorrect arguments: WNA (2 for 1) => wrong arguments</p>
</li>
</ul>
<p>Wording change:</p>
<ul>
<li>
<p>Change of language: WNA (at least 1) => WNA (0 for 1+)<br>
[].insert<br>
extend<br>
"".delete!<br>
"".count</p>
</li>
<li>
<p>Process.kill: WNA (0 for at least 2) => WNA (0 for 2+)</p>
</li>
</ul>
<p>Also, builtin functions calling <code>rb_scan_args</code> with both optional arguments and a rest argument would generate an error of the form "WNA (0 for 2..3+)". After this patch, this would now read "WNA (0 for 2+)", again for consistency. The only two such cases I found are in <code>ext/win32ole.c</code></p>
<p>In addition to giving a more consistent error handling, these commits pave the way to:</p>
<ul>
<li>improved error reporting for parameters with named parameters (forthcoming issue)</li>
<li>improved checking for Proc#curry (see bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Proc#curry doesn't always detect too many arguments (Closed)" href="https://bugs.ruby-lang.org/issues/5747">#5747</a>)</li>
</ul>
Ruby master - Bug #6048 (Closed): {Unbound}Method#hash doesn't always return the right value
https://bugs.ruby-lang.org/issues/6048
2012-02-20T15:19:08Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>{Unbound}Method#hash doesn't always return the right value.</p>
<pre><code>map, collect = Array.instance_method(:map), Array.instance_method(:collect)
map.eql?(collect) # => true
map.hash == collect.hash # => false
</code></pre>
<p>I'm tempted to think that this is an obvious bug with an obvious solution but let me state:</p>
<p>As per the documentation and the design of hash tables, if two objects are <code>eql?</code> then they must have the same hash.</p>
<p>Either <code>map</code> should not be <code>eql?</code> to <code>collect</code> or else their <code>hash</code> should be the same.</p>
<p>As they are identical methods, it is correct that they are <code>eql?</code>, so <code>hash</code> must return the same value.</p>
<p>My proposed behavior passes my strict superiority test and is also "straightforward" as I could find no intent for the current behavior.</p>
<p>One solution is to ensure that all aliased methods are defined using <code>rb_define_alias</code>, which appears to yield the same hash. Another is to compute the <code>hash</code> correctly. Maybe there is a third approach.</p>
<p>I'm not super confident I took the right approach, but here is a patch for the second one. I think it is more robust and more consistent with how <code>{Unbound}Method.eql?</code> is implemented. It may also fix other cases of mismatch between <code>eql?</code> and <code>hash</code>, I didn't investigate further.</p>
<p>I'd be grateful if someone could review the patch (Koichi?) and let me know if I took the right approach and if I put things in the right place.</p>
<a name="Thanks"></a>
<h2 >Thanks<a href="#Thanks" class="wiki-anchor">¶</a></h2>
<p>Marc-André</p>
Ruby master - Bug #6029 (Closed): Should OpenStruct implement #eql? and #hash?
https://bugs.ruby-lang.org/issues/6029
2012-02-15T12:33:15Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently, OpenStruct have no specialized #eql? and #hash, so:</p>
<pre><code>require 'ostruct'
x = OpenStruct.new(foo: 42)
y = x.dup
x == y # => true
x.eql?(y) # => false
</code></pre>
<p>This means that OpenStruct does not behave like Struct, Array, Hash and other structures by comparing its fields and values.</p>
<p>This also prevents using OpenStructs as hash keys (unless one uses the exact same object as the key), contrary to other structures.</p>
<p>Is there an historical reason for this?</p>
<p>How likely would it be that adding #eql? and #hash create conflict with some fields?</p>
Ruby master - Bug #6028 (Closed): OpenStruct.dup doesn't have all its methods
https://bugs.ruby-lang.org/issues/6028
2012-02-15T11:44:57Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Dupped OpenStructs don't have the same methods.</p>
<pre><code>x = OpenStuct.new(foo: 42)
x.dup.methods == x.methods # => false
x.respond_to?(:foo) # => true
x.dup.respond_to?(:foo) # => false
</code></pre>
Ruby master - Bug #5782 (Closed): File.binwrite doc and hash argument
https://bugs.ruby-lang.org/issues/5782
2011-12-20T16:14:02Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>The doc for <code>File.binwrite</code> doesn't mention the possibility of a fourth argument (option hash), unlike <code>File.write</code>. Judging from the code, this looks like an oversight.</p>
<p>Can we get confirmation that it does accept a fourth parameter and that the doc should be updated?</p>
<p>I would personally simplify the rdoc to state that it <code>File.binwrite</code> does exactly the same as <code>File.write</code> except that it opens the file in binary mode.</p>
<p>Noticed by Konstantin Haase.</p>
<a name="Thanks"></a>
<h2 >Thanks,<a href="#Thanks" class="wiki-anchor">¶</a></h2>
<p>Marc-Andre</p>
Ruby master - Bug #5747 (Closed): Proc#curry doesn't always detect too many arguments
https://bugs.ruby-lang.org/issues/5747
2011-12-12T09:30:21Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently, Proc#curry checks the validity of the <code>arity</code> argument and will raise an error if:</p>
<ol>
<li>arity is less than the number of required arguments or</li>
<li>arity is more than the maximum number of arguments<br>
Note that simple Procs always accept any number of arguments (even though they may be ignored), so (2) doesn't applies to them, only to lambda's and procs made from methods.</li>
</ol>
<p>#2 isn't done as well as it could in case of limited optional parameters:</p>
<pre><code>def Object.foo(a, b=42); end
def Object.bar(a, b); end
Object.method(:foo).to_proc.curry(3) # => curried proc which will raise an error only when passed it's 3rd parameter
Object.method(:bar).to_proc.curry(3) # => ArgumentError: wrong number of arguments (3 for 2)
Same thing with lambdas
</code></pre>
<p>My proposed fix passes SST:<br>
a) usefulness: "fail-early" principle <a href="https://blade.ruby-lang.org/ruby-core/24130">[ruby-core:24130]</a><br>
b) consistency: both methods can only accept a maximum of 2 parameters and are thus treated consistently when attempting to curry with more than 2 arguments<br>
c) intuitiveness and d) performance: similar</p>
<p>It is straightforward (but not obvious), as it passes NIT (but not ODT).</p>
Ruby master - Bug #5746 (Closed): Proc#curry too strict about lambda's arity.
https://bugs.ruby-lang.org/issues/5746
2011-12-12T02:08:08Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently, Proc#curry raises an error when you attempt to curry a lambda with optional (but limited) arguments:</p>
<pre><code>l = ->(arg = 42) {}
l.curry(1) # => ArgumentError: wrong number of arguments (1 for 0)
</code></pre>
<p>Note that Proc#curry behaves correctly if the Proc was created from a method, even though arguments are treated the same way:</p>
<pre><code>def Object.foo(arg = 42); end
m = Object.method(:foo).to_proc
m.class # => Proc, same as 'l'
m.lambda? # => true, same as 'l'
m.curry(1) # => curried proc
</code></pre>
<p>Referring to my evaluation method, my proposed fix passes SST:<br>
a) usefulness: way more useful, as it makes it possible to do something that is not currently possible<br>
b) consistency: makes it consistent with equivalent method<br>
c) intuitiveness and d) performance: similar</p>
<p>It is straightforward (but not obvious), as it passes NIT (but not ODT).</p>
<p>This bug is a consequence of the redmine issue 5694; this will be fixed automatically when 5694 is fixed.</p>
Ruby master - Bug #5694 (Closed): Proc#arity doesn't take optional arguments into account.
https://bugs.ruby-lang.org/issues/5694
2011-12-01T20:16:05Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently:</p>
<pre><code>->(foo = 42){}.arity # => 0, should be -1
</code></pre>
<p>This is contrary to the documentation and to what we should expect from the equivalent method definition.</p>
<p>Fixed in trunk, requesting backport for the 1.9 line.</p>
Ruby master - Bug #5307 (Closed): Matrix & subclasses
https://bugs.ruby-lang.org/issues/5307
2011-09-11T05:22:18Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Matrix doesn't deal properly with subclasses:</p>
<pre><code>Class.new(Matrix)[[42]].class # => Matrix
</code></pre>
Ruby master - Bug #5273 (Closed): Float#round returns the wrong floats for higher precision
https://bugs.ruby-lang.org/issues/5273
2011-09-05T05:43:55Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Float#round returns the wrong floats for higher precision.</p>
<p>Rounding can be off:<br>
2.5e-22.round(22) # => 2.0e-22</p>
<p>It can also return values that have extra decimals:<br>
2.5e-31.round(31) # => 3.0000000000000003e-31<br>
2.5e-36.round(36) # => 2.9999999999999998e-36</p>
<p>Both errors can occur at the same time too:<br>
2.5e-39.round(39) # => 2.0000000000000002e-39</p>
<p>I believe these errors occur only for ndigits >= 22. For ndigits > 22, 10**(-ndigits) is not an exact Float (as 5 ** 23 won't fit in the 53 bits of a double's mantissa). For ndigits < 22, there should be enough bits left to avoid rounding errors.</p>
<p>For ndigits >= 22, the algorithm to use should be similar to the one used to convert doubles to string.</p>
<p>Hopefully, this is the last bug for #round with a given precision.</p>
Ruby master - Bug #5228 (Closed): Integer#round fails on some big negative numbers
https://bugs.ruby-lang.org/issues/5228
2011-08-25T07:50:29Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Integer#round fails for some big negative numbers:</p>
<p>(+25 * 10<strong>70).round(-71) # => 30...00<br>
(-25 * 10</strong>70).round(-71) # => -20...00, should be -30...00</p>
Ruby master - Bug #5227 (Closed): Float#round fails on corner cases
https://bugs.ruby-lang.org/issues/5227
2011-08-25T06:03:50Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Float#round fails on some corner cases:</p>
<p>42.0.round(300) # => 42.0<br>
42.0.round(308) # => Infinity, should be 42.0<br>
42.0.round(309) # => 42.0</p>
<p>1.0e307.round(1) # => 1.0e307<br>
1.0e307.round(2) # => Infinity, should be 1.0e307</p>
<p>These occur when the exponent of the intermediate value overflows.</p>
<p>The original code already had criteria for extreme values, but we can find much tighter ones, as explained in the patch below. This fixes the bugs above and optimizes for most trivial cases.</p>
<p>I'd be grateful if someone could look it over before I commit it, thanks.</p>
<p>diff --git a/numeric.c b/numeric.c<br>
index 272bbd1..22608c9 100644<br>
--- a/numeric.c<br>
+++ b/numeric.c<br>
@@ -1491,18 +1491,37 @@ flo_round(int argc, VALUE *argv, VALUE num)<br>
VALUE nd;<br>
double number, f;<br>
int ndigits = 0;</p>
<ul>
<li>
<p>int binexp;<br>
long val;</p>
<p>if (argc > 0 && rb_scan_args(argc, argv, "01", &nd) == 1) {<br>
ndigits = NUM2INT(nd);<br>
}<br>
number = RFLOAT_VALUE(num);</p>
</li>
</ul>
<ul>
<li>f = pow(10, abs(ndigits));</li>
<li>
<li>if (isinf(f)) {</li>
<li>
<pre><code> if (ndigits < 0) number = 0;
</code></pre>
</li>
<li>}</li>
<li>else {</li>
</ul>
<ul>
<li>frexp (number , &binexp);</li>
<li>
</ul>
<p>+/* Let <code>exp</code> be such that <code>number</code> is written as: "0.#{digits}e#{exp}",</p>
<ul>
<li>i.e. such that 10 ** (exp - 1) <= |number| < 10 ** exp</li>
<li>Recall that up to 17 digits can be needed to represent a double,</li>
<li>so if ndigits + exp >= 17, the intermediate value (number * 10 ** ndigits)</li>
<li>will be an integer and thus the result is the original number.</li>
<li>If ndigits + exp <= 0, the result is 0 or "1e#{exp}", so</li>
<li>if ndigits + exp < 0, the result is 0.</li>
<li>We have:</li>
<li>
<pre><code> 2 ** (binexp-1) <= |number| < 2 ** binexp
</code></pre>
</li>
<li>
<pre><code> 10 ** ((binexp-1)/log_2(10)) <= |number| < 10 ** (binexp/log_2(10))
</code></pre>
</li>
<li>
<pre><code> If binexp >= 0, and since log_2(10) = 3.322259:
</code></pre>
</li>
<li>
<pre><code> 10 ** (binexp/4 - 1) < |number| < 10 ** (binexp/3)
</code></pre>
</li>
<li>
<pre><code> binexp/4 <= exp <= binexp/3
</code></pre>
</li>
<li>
<pre><code> If binexp <= 0, swap the /4 and the /3
</code></pre>
</li>
<li>
<pre><code> So if ndigits + binexp/(3 or 4) >= 17, the result is number
</code></pre>
</li>
<li>
<pre><code> If ndigits + binexp/(4 or 3) < 0 the result is 0
</code></pre>
</li>
</ul>
<p>+*/</p>
<ul>
<li>if ((long)ndigits * (4 - (binexp < 0)) + binexp < 0) {</li>
<li>
<pre><code> number = 0;
</code></pre>
</li>
<li>}</li>
<li>else if ((long)(ndigits - 17) * (3 + (binexp < 0)) + binexp < 0) {</li>
<li>
<pre><code> f = pow(10, abs(ndigits));
if (ndigits < 0) {
double absnum = fabs(number);
if (absnum < f) return INT2FIX(0);
</code></pre>
</li>
</ul>
Ruby master - Bug #5179 (Closed): Complex#rationalize and to_r with approximate zeros
https://bugs.ruby-lang.org/issues/5179
2011-08-10T10:41:15Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently, Complex#rationalize and Complex#to_r raise a RangeError if the imaginary part is nonzero <em>or is a Float</em>. Note that a BigDecimal(0) is accepted, though:</p>
<pre><code>Complex(1, 0).to_r # => Rational(1,1)
Complex(1, BigDecimal("0.0")).to_r # => Rational(1,1)
Complex(1, 0.0).to_r # => RangeError
</code></pre>
<p>This is inconsistent. I recommend not raising an error for 0.0 (Float or BigDecimal). Any objection?</p>
Ruby master - Bug #5070 (Closed): CSV.generate should not modify the given option hash
https://bugs.ruby-lang.org/issues/5070
2011-07-22T04:23:02Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>Currently:</p>
<pre><code>CSV.generate( {}.freeze ) # => RuntimeError: can't modify frozen Hash
</code></pre>
<p>I'm not sure where these tests would ideally go; In the attached patch, I've put them at the end of csv/test_interface</p>
<p>If you can, please make the modifications you see fit, or else I'll commit this in a of week or two.</p>
<p>(From <a href="http://stackoverflow.com/questions/6759487/ruby-hash-object-changed-by-csv-library" class="external">http://stackoverflow.com/questions/6759487/ruby-hash-object-changed-by-csv-library</a> )</p>
Ruby master - Bug #3434 (Closed): Specs for coercion?
https://bugs.ruby-lang.org/issues/3434
2010-06-13T15:29:24Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
What are the official specs of coercion for mathematical classes?</p>
<p>I will take Matrix as an example, but my questions are meant to be for the general case.</p>
<p>My understanding is that for a <code>obj.coerce(obj_2)</code> should return <code>[compatible_2, compatible]</code> such that <code>compatible2.send(some_operation, compatible)</code> returns (if possible) a meaningful result.</p>
<p>Can we assume anything more about coercion? I'm asking because I find in test_matrix (@m1 being a Matrix):</p>
<p>def test_scalar_mul<br>
s1 = @m1.coerce(1).first<br>
assert_equal(Matrix[[1]], (s1 * 1) * Matrix[[1]])<br>
assert_equal(Vector[2], s1 * Vector[2])<br>
assert_equal(Matrix[[2]], s1 * Matrix[[2]])<br>
o = Object.new<br>
def o.coerce(x)<br>
[1, 1]<br>
end<br>
assert_equal(1, s1 * o)<br>
end</p>
<ol>
<li>Should the first and last assert work? Are implementers of other mathematical classes mandated/encouraged to provide that level of compatibility? Are users of <code>coerce</code> encouraged (or guaranteed success) when doing any other operation than <code>compatible2 * compatible</code> or similar?</li>
</ol>
<p>My feeling is that the only thing one should do with the results of coerce is to call an operation on the first element and pass the second element. Doing operations using only one of the two returned elements with another new object should yield undetermined results.</p>
<p>If this is the case, I feel the Matrix library would be best to assume that Scalar#* is called with a Matrix or Vector (remember that the Scalar is not meant to be used directly by anybody else than the Matrix lib), and these two assert would <em>not</em> work.</p>
<ol start="2">
<li>
<p>The second assert is clearly implementation dependant. In the current implementation, both Vector and Matrix use Matrix::Scalar as a temporary class, but that could change.</p>
</li>
<li>
<p>I am assuming that compatible doesn't have to be equal?, eql? or == to obj nor of the same class, and the same is true for compatible_2 vs obj_2, right? Thus the third assert isn't a spec guaranteed for all implementations.</p>
</li>
<li>
<p>Finally, a somewhat trivial question: should <code>obj.coerce(obj_2)</code> succeed if <code>obj</code> and <code>obj_2</code> are of the same class (and presumably return <code>[obj_2, obj]</code>)? Clearly this is not very useful, but the specs should be made precise.</p>
</li>
</ol>
<p>This is the case for Numeric and is explicit in the documentation but fails for Matrix:</p>
<pre><code> Matrix.I(2).coerce(Matrix.I(2)) # => TypeError: Matrix can't be coerced into Matrix
</code></pre>
<p>Coercion should always work for the trivial case of two objects of the same class, right?</p>
<a name="Thanks"></a>
<h2 >Thanks.<a href="#Thanks" class="wiki-anchor">¶</a></h2>
<p>Marc-André<br>
=end</p>
Ruby master - Bug #3352 (Rejected): Delegates: protected methods
https://bugs.ruby-lang.org/issues/3352
2010-05-27T15:55:26Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
require 'delegate'</p>
<pre><code> class X
protected
def pro
:foo
end
end
obj = X.new
obj.pro #=> NoMethodError: protected method `pro' called for #<X:0x000001008a2a68>
SimpleDelegator.new(obj).pro #=> :foo
</code></pre>
<p>I feel it would be more sensible to raise a NoMethodError.</p>
<p>No test seem to be testing for protected access, nor does RubySpec.</p>
<p>Unless there is objection, I'll commit the following:</p>
<p>diff --git a/lib/delegate.rb b/lib/delegate.rb<br>
index f366091..93fbc37 100644<br>
--- a/lib/delegate.rb<br>
+++ b/lib/delegate.rb<br>
@@ -141,7 +141,7 @@ class Delegator < BasicObject<br>
def method_missing(m, *args, &block)<br>
target = self.<strong>getobj</strong><br>
begin</p>
<ul>
<li>
<pre><code> target.respond_to?(m) ? target.__send__(m, *args, &block) : super(m, *args, &block)
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> target.respond_to?(m) ? target.public_send(m, *args, &block) : super
</code></pre>
ensure<br>
$@.delete_if {|t| %r"\A#{Regexp.quote(<strong>FILE</strong>)}:#{<strong>LINE</strong>-2}:"o =~ t} if $@<br>
end<br>
=end</li>
</ul>
Ruby master - Bug #3350 (Closed): Protected methods & documentation
https://bugs.ruby-lang.org/issues/3350
2010-05-27T15:28:46Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
The official doc currently states that Object#methods "returns a list of the names of methods publicly accessible".</p>
<p>Similarly, Module#instance_methods states that it returns "the public methods" of the Module. Note that the doc was modified in r19900, but I feel the wording "instance method that is callable from outside" still implies public only.</p>
<p>The current behavior doesn't fit the doc, since protected methods are also matched:</p>
<pre><code> class X
def protected_method; end
protected :protected_method
end
X.new.methods.include?(:protected_method) #=> true
X.instance_methods.include?(:protected_method) #=> true
</code></pre>
<p>The documentation for Module#method_defined? on the other states it matches public and protected methods.</p>
<p>Should I change the doc to reflect the current behavior, as per the patch below?</p>
<p>I'm asking in part because I lack experience with protected methods and I am surprised by the fact that protected methods are matched by these "default" methods.</p>
<p>The fact that Object#respond_to? also matches protected is even less practical since there is no "public-only" equivalent. I might be mistaken, but I believe that the only way of knowing if obj responds publicly to :foo is to do something like</p>
<pre><code> publicly_responds = obj.public_method(:foo) rescue false
</code></pre>
<p>I dislike the fact that obj.respond_to?(:foo) && obj.foo might raise a NoMethodError.</p>
<p>It looks like this was discussed a in [ruby_dev:40461], but I don't know the outcome.</p>
<p>I'm curious: what examples exist where one would want to match public and protected methods but not private ones?</p>
<p>Matz, is there any chance the handling of #respond_to?, #methods, etc..., with regards to protected methods will change (in 1.9.2 or later)?</p>
<p>--<br>
Marc-André</p>
<p>diff --git a/class.c b/class.c<br>
index c586f7a..683fa7b 100644<br>
--- a/class.c<br>
+++ b/class.c<br>
@@ -865,8 +865,8 @@ class_instance_method_list(int argc, VALUE *argv, VALUE mod, int (*func) (ID, lo</p>
<ul>
<li>call-seq:</li>
<li>
<pre><code>mod.instance_methods(include_super=true) -> array
</code></pre>
</li>
<li>
</ul>
<ul>
<li>
<ul>
<li>Returns an array containing the names of instance methods that is callable</li>
</ul>
</li>
<li>
<ul>
<li>from outside in the receiver. For a module, these are the public methods;</li>
</ul>
</li>
</ul>
<ul>
<li>
<ul>
<li>Returns an array containing the names of the public and protected instance</li>
</ul>
</li>
<li>
<ul>
<li>methods in the receiver. For a module, these are the public and protected methods;</li>
<li>for a class, they are the instance (not singleton) methods. With no</li>
<li>argument, or with an argument that is <code>false</code>, the</li>
<li>instance methods in <i>mod</i> are returned, otherwise the methods<br>
@@ -954,6 +954,7 @@ rb_class_public_instance_methods(int argc, VALUE *argv, VALUE mod)</li>
<li>Returns an array of the names of singleton methods for <i>obj</i>.</li>
<li>If the optional <i>all</i> parameter is true, the list will include</li>
<li>methods in modules included in <i>obj</i>.</li>
</ul>
</li>
<li>
<ul>
<li>Only public and protected singleton methods are returned.</li>
<li>
<li>
<pre><code>module Other
</code></pre>
</li>
<li>
<pre><code> def three() end
</code></pre>
</li>
</ul>
</li>
</ul>
<p>diff --git a/object.c b/object.c<br>
index a7f05a1..351d16f 100644<br>
--- a/object.c<br>
+++ b/object.c<br>
@@ -1755,7 +1755,7 @@ rb_mod_const_defined(int argc, VALUE *argv, VALUE mod)</p>
<ul>
<li>call-seq:</li>
<li>
<pre><code>obj.methods -> array
</code></pre>
</li>
<li>
</ul>
<ul>
<li>
<ul>
<li>Returns a list of the names of methods publicly accessible in</li>
</ul>
</li>
</ul>
<ul>
<li>
<ul>
<li>Returns a list of the names of public and protected methods of</li>
<li>
<i>obj</i>. This will include all the methods accessible in</li>
<li>
<i>obj</i>'s ancestors.</li>
<li>
</ul>
</li>
</ul>
<p>=end</p>
Ruby master - Bug #3225 (Closed): lib/uri/mailto.rb slightly wrong regexp
https://bugs.ruby-lang.org/issues/3225
2010-04-30T13:24:56Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Looking for example of the 3rd parameter of value 'N' for Regexp.new, I noticed in lib/uri/mailto.rb</p>
<p>HEADER_REGEXP = Regexp.new(HEADER_PATTERN, 'N').freeze</p>
<p>Unless I'm mistaken, the 'N' in second position is simply a flag for case insensitivity, but HEADER_PATTERN already is, so it should either be</p>
<p>HEADER_REGEXP = Regexp.new(HEADER_PATTERN).freeze</p>
<p>or</p>
<p>HEADER_REGEXP = Regexp.new(HEADER_PATTERN, nil, 'N').freeze</p>
<p>but I don't know which one...<br>
=end</p>
Ruby master - Bug #3224 (Closed): Regexp.new("...", nil, "n") is not documented
https://bugs.ruby-lang.org/issues/3224
2010-04-30T13:15:06Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
While fixing the error messages for the number of parameters ( r27558 ), I noticed that Regexp.new accepts a third undocumented parameter.</p>
<p>Is it supported? If so it should be documented.</p>
<p>I also note that test_regexp.rb tests for the third parameter being "u", even though this has no effect. Maybe these tests should be removed?<br>
=end</p>
Ruby master - Bug #3192 (Closed): Missing Set#keep_if, select! [patch]
https://bugs.ruby-lang.org/issues/3192
2010-04-23T14:40:16Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Set (& SortedSet) were forgotten when adding keep_if and select!</p>
<p>Unless there is objection, I'll commit the attached patch (and add tests to RubySpec).<br>
=end</p>
Ruby master - Bug #3169 (Closed): RDoc crossref confused by instance and class methods having sam...
https://bugs.ruby-lang.org/issues/3169
2010-04-19T09:39:40Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
The documentation for the two methods below will both have a reference to X.foo (which appeared first). The "See X#foo" should reference to the instance method instead.</p>
<p>class X<br>
# The class method. See X#foo<br>
def self.foo<br>
end</p>
<pre><code> # The instance method. See X.foo
def foo
end
</code></pre>
<p>end<br>
=end</p>
Ruby master - Bug #3128 (Closed): Randomness specs
https://bugs.ruby-lang.org/issues/3128
2010-04-11T15:34:01Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
What should be the Ruby specs for the new Random class (and existing Kernel.{s}rand)?</p>
<p>More precisely: what should one expect of any Ruby implementation?</p>
<p>Several degrees of similarity with MRI are possible:</p>
<p>Say r = Random.new(42) and N is an Integer</p>
<ol start="0">
<li>r.rand(N) is included in 0...N</li>
<li>r.rand(N) will eventually return all values in 0...N</li>
<li>r.rand(N) will return any particular value in 0...N with a probability of around 1/N<br>
<insert any any of the known random tests and/or a minimal period></li>
<li>r is a Mersenne Twister</li>
<li>r is MT19937</li>
<li>r.rand(N) generates the same particular string on all platforms</li>
</ol>
<p>Implementers are ultimately free to choose whichever implementation they prefer, of course.</p>
<p>Still, it would be preferable to state what is the expect behavior for the Ruby language, not just for MRI. If MRI's guarantees are stronger, these should be stated as such.</p>
<p>Current state of affairs:</p>
<p>The documentation for Random class states that it is a Mersenne Twister pseudo number generator (but doesn't state which), so this corresponds to level (3) above.</p>
<p>Kernel.rand states that <em>currently</em>, r is a modified MT19937.</p>
<p>The Ruby Standardization WG Draft doesn't document Kernel.rand yet (nor Random, of course).</p>
<p>Rubinius' implementation currently guarantees level 0 (and also level 1 if N is not too big)</p>
<p>JRuby's implementation guarantees level 1 (and also level 2 if N is not too big)</p>
<p>Python and Java both guarantee the same particular sequence; other algorithms might be available as subclasses of their Random class.</p>
<hr>
<p>My personal choice would be in line with Java and Python: insure the exact same sequence for the Random class. Implementations are free to provide subclasses of Random for different/better/faster algorithms.</p>
<p>If deemed preferable, Kernel.rand could have much lower required standards to allow for better speed, in which case level (2) above seems like the strict minimum.<br>
=end</p>
Ruby master - Bug #3104 (Closed): Random: seeding issues
https://bugs.ruby-lang.org/issues/3104
2010-04-07T15:08:35Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
I think there are a couple of very small errors with the seeding of the Random class.</p>
<ol>
<li>
<p>Seeding sometimes ignores the high bit of seed data.</p>
<p>Random.new((1<<64)-1).rand == Random.new((1 << 65) -1).rand</p>
<a name="gt-true-should-be-false"></a>
<h1 >=> true, should be false<a href="#gt-true-should-be-false" class="wiki-anchor">¶</a></h1>
</li>
</ol>
<p>Probably some leftover code?</p>
<p>diff --git a/random.c b/random.c<br>
index 02d081c..447e59f 100644<br>
--- a/random.c<br>
+++ b/random.c<br>
@@ -411,8 +411,6 @@ rand_init(struct MT *mt, VALUE vseed)<br>
init_genrand(mt, buf[0]);<br>
}<br>
else {</p>
<ul>
<li>
<pre><code> if (buf[len-1] == 1) /* remove leading-zero-guard */
</code></pre>
</li>
<li>
<pre><code> len--;
init_by_array(mt, buf, len);
</code></pre>
}<br>
if (buf != buf0) xfree(buf);</li>
</ul>
<ol start="2">
<li>
<p>Treatment of negative seed values is currently platform dependent for all negative fixnums. From the same negative seed, the random sequence can be different on 32 bit platforms than on 64 bit ones.</p>
<p>Random.new(-1).rand == Random.new((1<<63) -1).rand</p>
<a name="gt-true-on-64-bit-platform-false-on-32-bit"></a>
<h1 >=> true on 64 bit platform, false on 32 bit<a href="#gt-true-on-64-bit-platform-false-on-32-bit" class="wiki-anchor">¶</a></h1>
<p>Random.new(-1).rand == Random.new((1<<31) -1).rand</p>
<a name="gt-false-on-64-bit-platform-true-on-32-bit"></a>
<h1 >=> false on 64 bit platform, true on 32 bit<a href="#gt-false-on-64-bit-platform-true-on-32-bit" class="wiki-anchor">¶</a></h1>
</li>
</ol>
<p>The simple solution below ignores the sign (which is what's done in case of negative Bignum). This means that the same values will result from seeding with x or -x. Another solution would be to use the lowest bit for the sign (for both fixnums and bignums) so as to avoid this collision, or raise an error in case of negative seeds.</p>
<p>diff --git a/random.c b/random.c<br>
index 02d081c..272f7b5 100644<br>
--- a/random.c<br>
+++ b/random.c<br>
@@ -367,6 +367,7 @@ rand_init(struct MT *mt, VALUE vseed)<br>
{<br>
volatile VALUE seed;<br>
long blen = 0;</p>
<ul>
<li>long fixnum_seed;<br>
int i, j, len;<br>
unsigned int buf0[SIZEOF_LONG / SIZEOF_INT32 * 4], *buf = buf0;</li>
</ul>
<p>@@ -374,9 +375,11 @@ rand_init(struct MT *mt, VALUE vseed)<br>
switch (TYPE(seed)) {<br>
case T_FIXNUM:<br>
len = 1;</p>
<ul>
<li>
<pre><code> buf[0] = (unsigned int)(FIX2ULONG(seed) & 0xffffffff);
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> fixnum_seed = FIX2LONG(seed);
</code></pre>
</li>
<li>
<pre><code> if (fixnum_seed < 0) fixnum_seed = -fixnum_seed;
</code></pre>
</li>
<li>
<pre><code> buf[0] = (unsigned int)(fixnum_seed & 0xffffffff);
</code></pre>
</li>
</ul>
<p>#if SIZEOF_LONG > SIZEOF_INT32</p>
<ul>
<li>
<pre><code> if ((buf[1] = (unsigned int)(FIX2ULONG(seed) >> 32)) != 0) ++len;
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if ((buf[1] = (unsigned int)(fixnum_seed >> 32)) != 0) ++len;
</code></pre>
</li>
</ul>
<p>#endif<br>
break;<br>
case T_BIGNUM:</p>
<ol start="3">
<li>Finally, I was wondering if there wasn't a typo trashing some of the bits in the initial states when seeding with an array:</li>
</ol>
<p>diff --git a/random.c b/random.c<br>
index 02d081c..f3db095 100644<br>
--- a/random.c<br>
+++ b/random.c<br>
@@ -151,7 +151,7 @@ init_by_array(struct MT *mt, unsigned int init_key[], int key_length)<br>
if (i>=N) { mt->state[0] = mt->state[N-1]; i=1; }<br>
}</p>
<ul>
<li>mt->state[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */</li>
</ul>
<ul>
<li>mt->state[0] |= 0x80000000U; /* MSB is 1; assuring non-zero initial array */<br>
}</li>
</ul>
<p>static void</p>
<p>These changes will surely create test failures which should be trivial to fix.<br>
=end</p>
Ruby master - Bug #3089 (Closed): limited size for Array#combination [patch]
https://bugs.ruby-lang.org/issues/3089
2010-04-04T05:54:56Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
I would expect the following to work, but it raises an error</p>
<p>(0..100).to_a.combination(50).first(42)<br>
# => RangeError: too big for combination</p>
<p>There is a limit of 1 << 31 potential results (or 1 <<63, depending on the platform).</p>
<p>Since there is an explicit test for this, I learned the hard way I better ask if there is a valid reason for this artificial limit for #combination ?</p>
<p>If not, and unless there is objection, I'll commit the attached patch.</p>
<p>Note: I noticed this when implementing the block form of #product where a similar limit exists. Since #product without a block needs to return an array of this size, it is sensible that an error is raised in that case.<br>
When an block is given, though, I didn't see why there should be a limit, so the limitation applies only to the form without a block. This does mean, though, that arr.product(...) might not behave the same as arr.to_enum(:product, ...).to_a, at least until Enumerators have a length method (see issue <a class="issue tracker-2 status-5 priority-4 priority-default closed" title="Feature: the length for an enumerator generated by Array#permutation and Array#combination (Closed)" href="https://bugs.ruby-lang.org/issues/2673">#2673</a>)<br>
=end</p>
Ruby master - Bug #3027 (Closed): Random#rand(nil)
https://bugs.ruby-lang.org/issues/3027
2010-03-28T09:06:42Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Hi Nobu.</p>
<p>Looking at Random#rand, I notice that passing nil has the same result as not passing any argument.</p>
<p>Either it should raise an ArgumentError like the documentation implies, or else the documentation should be modified.</p>
<p>I would argue to raise an error because:</p>
<ul>
<li>it is easy to pass nothing, or pass 1.0 instead, and get the same result if that is what is desired</li>
<li>it could hide an error in the code, where the result is unexpectedly nil but the programmer didn't think about it (like whiny nils in rails)<br>
=end</li>
</ul>
Ruby master - Bug #3022 (Closed): What are $. and ARGF.lineno ?
https://bugs.ruby-lang.org/issues/3022
2010-03-27T04:13:59Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin</p>
<ol>
<li>$. is not officially documented.</li>
</ol>
<p>This makes it difficult to know if it works as expected or not...</p>
<p>The Ruby Prog Language (Flanagan & Matz) states:<br>
"The number of the last line read from the current input file. Equivalent to ARGF.lineno."</p>
<p>This is not true in trunk, as demonstrated by:</p>
<p>$ rubydev -e "<br>
ARGF.gets<br>
File.open('/etc/passwd'){|f| f.gets; f.gets}<br>
p $., ARGF.lineno<br>
" /etc/hosts<br>
2<br>
1</p>
<p>What is the "current input file"? Not clear, but it's not thread local, as shown:</p>
<p>$ rubydev -e "<br>
p $.<br>
Thread.new{File.open('/etc/passwd').gets; p $. }.join;<br>
p $.<br>
"<br>
0<br>
1<br>
1</p>
<ol start="2">
<li>ARGF.lineno does not conform to its doc.</li>
</ol>
<p>The doc states:</p>
<p>Returns the current line number of the current file in ARGF. This value<br>
can be set manually with ARGF.lineno=.</p>
<p>Reading this, I would expect ARGF.lineno to be the same as ARGF.to_io.lineno.</p>
<p>That is not the case:</p>
<p>rubydev -e 'p "#{ARGF.lineno} #{ARGF.to_io.lineno}" while ARGF.gets' /etc/hosts /etc/passwd<br>
"1 1"<br>
"2 2"<br>
...<br>
"25 1"<br>
"26 2"<br>
...</p>
<ol>
<li>
<p>Maybe the best definition would be that $. returns the number of line read operations issued, from the last time an IO was read in the current thread?</p>
</li>
<li>
<p>I suggest the documentation of ARGF.lineno be changed to:</p>
</li>
</ol>
<p>Returns the current line number of ARGF as a whole. This value<br>
can be set manually with ARGF.lineno=.</p>
<p>See also <a href="https://blade.ruby-lang.org/ruby-core/26303">[ruby-core:26303]</a><br>
=end</p>
Ruby 1.8 - Bug #3011 (Closed): caller for recursive function
https://bugs.ruby-lang.org/issues/3011
2010-03-25T10:38:53Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
For some reason, Ruby 1.8 will skip multiple copies of the same method. In case of a recursive function call, the behavior is different from Ruby 1.9 and seems wrong.</p>
<p>Here's the rubyspec I just committed:</p>
<pre><code> it "returns one entry per call, even for recursive methods" do
def recurse(n)
return caller if n <= 0
recurse(n-1)
end
(recurse(3).size - recurse(2).size).should == 1
end
</code></pre>
<p>The following patch doesn't seem to yield any new failure with make test, make test-all, nor the caller specs:</p>
<p>diff --git a/eval.c b/eval.c<br>
index 3407548..65fb970 100644<br>
--- a/eval.c<br>
+++ b/eval.c<br>
@@ -6468,9 +6468,6 @@ backtrace(lev)<br>
}<br>
for (; frame && (n = frame->node); frame = frame->prev) {<br>
if (frame->prev && frame->prev->last_func) {</p>
<ul>
<li>
<pre><code> if (frame->prev->node == n) {
</code></pre>
</li>
<li>
<pre><code> if (frame->prev->last_func == frame->last_func) continue;
</code></pre>
</li>
<li>
<pre><code> }
snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
n->nd_file, nd_line(n),
rb_id2name(frame->prev->last_func));
</code></pre>
</li>
</ul>
<p>Nobu, can you recall what was the reason for these lines ( r10593 ) ?<br>
=end</p>
Ruby master - Bug #2830 (Closed): Some methods raise ArgumentError instead of TypeError
https://bugs.ruby-lang.org/issues/2830
2010-03-02T13:45:08Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Some methods of Ruby 1.9 expect integers/reals and call internally nurat_int_value/nurat_int_check. These functions raise an ArgumentError when the argument is not an Integer, instead of a TypeError.</p>
<p>Thus:<br>
42.gcd(:foo) # => ArgumentError, should be TypeError<br>
42.lcm(:foo) # => ditto<br>
42.gcdlcm(:foo) # => ditto<br>
Rational(:foo,1) # => ditto</p>
<p>Note that on the other hand:<br>
Rational(nil, 1) # => TypeError<br>
Rational(:foo) # => TypeError</p>
<p>In a similar fashion:<br>
Complex.rect(nil) # => ArgumentError, should be TypeError<br>
Complex.polar(nil) # => ditto</p>
<p>Unless there is objection, I will commit the following patch (and fix RubySpec):</p>
<p>diff --git a/complex.c b/complex.c<br>
index 214d3a2..6742257 100644<br>
--- a/complex.c<br>
+++ b/complex.c<br>
@@ -377,7 +377,7 @@ nucomp_real_check(VALUE num)<br>
break;<br>
default:<br>
if (!k_numeric_p(num) || !f_real_p(num))</p>
<ul>
<li>
<pre><code> rb_raise(rb_eArgError, "not a real");
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> rb_raise(rb_eTypeError, "not a real");
</code></pre>
}<br>
}</li>
</ul>
<p>diff --git a/rational.c b/rational.c<br>
index 65d3cf4..f5a6d26 100644<br>
--- a/rational.c<br>
+++ b/rational.c<br>
@@ -419,7 +419,7 @@ nurat_int_check(VALUE num)<br>
break;<br>
default:<br>
if (!k_numeric_p(num) || !f_integer_p(num))</p>
<ul>
<li>
<pre><code> rb_raise(rb_eArgError, "not an integer");
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> rb_raise(rb_eTypeError, "not an integer");
</code></pre>
}<br>
}<br>
=end</li>
</ul>
Ruby master - Bug #2829 (Closed): Missing documentation for Exception subclasses.
https://bugs.ruby-lang.org/issues/2829
2010-03-02T13:38:53Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
I noticed that the documentation for Exception subclasses are either that of Exception itself, or just plain non-sensical because they are actually missing (see ZeroDivisionError, FiberError, ...)</p>
<p>It would be preferable if the Exception classes were at least briefly described.</p>
<p>I've made a first draft of a description for all Exception subclasses, and would encourage anyone interested in improving it by editing the wiki:</p>
<p><a href="http://redmine.ruby-lang.org/wiki/ruby/ExceptionClassesDoc" class="external">http://redmine.ruby-lang.org/wiki/ruby/ExceptionClassesDoc</a></p>
<p>Thanks.<br>
=end</p>
Ruby master - Bug #2770 (Closed): Matrix: determinant for rectangular matrices should raise an er...
https://bugs.ruby-lang.org/issues/2770
2010-02-21T04:46:28Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Keiju,</p>
<p>$ rubydev -r matrix -e "puts Matrix[[1], [2], [3]].determinant"<br>
0</p>
<p>This corresponds to the documentation, but is not mathematically valid, since the determinant for rectangular matrices is not defined (at least for now! <a href="http://bit.ly/bwW7Gs" class="external">http://bit.ly/bwW7Gs</a> )</p>
<p>I believe an error should be thrown, similar to:<br>
$ rubydev -r matrix -e "puts Matrix[[1], [2], [3]].trace"<br>
/usr/local/rubydev/lib/ruby/1.9.1/matrix.rb:837:in <code>trace': Matrix dimension mismatch (ExceptionForMatrix::ErrDimensionMismatch) from -e:1:in </code>'</p>
<p>Since this is an API change, I attached a patch and will wait for your approval before committing.<br>
=end</p>
Ruby master - Bug #2525 (Closed): URI#normalize incomplete
https://bugs.ruby-lang.org/issues/2525
2009-12-24T16:38:28Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
"<a href="hTTp://example.com/" class="external">hTTp://example.com/</a>" and "<a href="http://exa%4dple.com/" class="external">http://exa%4dple.com/</a>" should both be normalized to "<a href="http://example.com/" class="external">http://example.com/</a>" as per RFC 3986.</p>
<p>They currently are not and thus not considered ==.</p>
<p>Tests added to RubySpec<br>
=end</p>
Ruby master - Bug #2499 (Closed): InstructionSequence.dissassemble can crash
https://bugs.ruby-lang.org/issues/2499
2009-12-19T11:52:54Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
I was trying to understand what InstructionSequence.disassemble is supposed to do when:</p>
<p>$ rubydev -e 'RubyVM::InstructionSequence.disassemble("x".method(:upcase))'<br>
-e:1: [BUG] Segmentation fault<br>
ruby 1.9.2dev (2009-12-19 trunk 26121) [x86_64-darwin10.2.0]</p>
<h2>-- control frame ----------<br>
c:0004 p:---- s:0010 b:0010 l:000009 d:000009 CFUNC :disassemble<br>
c:0003 p:0027 s:0006 b:0006 l:0022c8 d:001e98 EVAL -e:1<br>
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH<br>
c:0001 p:0000 s:0002 b:0002 l:0022c8 d:0022c8 TOP</h2>
<p>-e:1:in <code><main>' -e:1:in </code>disassemble'</p>
<p>-- C level backtrace information -------------------------------------------</p>
<p>[NOTE]<br>
You may have encountered a bug in the Ruby interpreter or extension libraries.<br>
Bug reports are welcome.<br>
For details: <a href="http://www.ruby-lang.org/bugreport.html" class="external">http://www.ruby-lang.org/bugreport.html</a></p>
<p>Abort trap<br>
=end</p>
Ruby master - Bug #2496 (Closed): Delegate: #methods and #public_methods should return delegated ...
https://bugs.ruby-lang.org/issues/2496
2009-12-19T10:38:20Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
require 'delegate'<br>
s = SimpleDelegator.new "Hello, world!"<br>
s.respond_to? :upcase # => true<br>
s.method :upcase # => #<Method : SimpleDelegator#upcase><br>
s.methods.include? :upcase # => false, true expected</p>
<p>Similar problem with public_methods.<br>
I propose that they return the union of methods from the delegator object and the methods of the object delegated to (only the public ones, since other ones are not forwarded)</p>
<p>Patch:<br>
diff --git a/lib/delegate.rb b/lib/delegate.rb<br>
index 77804e4..2fd5b49 100644<br>
--- a/lib/delegate.rb<br>
+++ b/lib/delegate.rb<br>
@@ -158,6 +158,22 @@ class Delegator<br>
end</p>
<pre><code>#
</code></pre>
<ul>
<li>
<a name="Returns-the-methods-available-to-this-delegate-object-as-the-union"></a>
<h1 >Returns the methods available to this delegate object as the union<a href="#Returns-the-methods-available-to-this-delegate-object-as-the-union" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="of-this-objects-methods-and-the-public-methods-of-__getobj__"></a>
<h1 >of this object's methods and the public methods of __getobj__.<a href="#of-this-objects-methods-and-the-public-methods-of-__getobj__" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>def methods</li>
<li>self.<strong>getobj</strong>.public_methods | super</li>
<li>end</li>
<li>
<li>
<h1></h1>
</li>
<li>
<a name="Returns-the-methods-available-to-this-delegate-object-as-the-union-of-this-object"></a>
<h1 >Returns the methods available to this delegate object as the union of this object<a href="#Returns-the-methods-available-to-this-delegate-object-as-the-union-of-this-object" class="wiki-anchor">¶</a></h1>
</li>
<li>
<a name="and-the-methods-of-__getobj__"></a>
<h1 >and the methods of __getobj__.<a href="#and-the-methods-of-__getobj__" class="wiki-anchor">¶</a></h1>
</li>
<li>
<h1></h1>
</li>
<li>def public_methods(all=true)</li>
<li>self.<strong>getobj</strong>.public_methods(all) | super</li>
<li>end</li>
<li>
<li>
<h1></h1>
<a name="Returns-true-if-two-objects-are-considered-same"></a>
<h1 >Returns true if two objects are considered same.<a href="#Returns-true-if-two-objects-are-considered-same" class="wiki-anchor">¶</a></h1>
<h1></h1>
def ==(obj)<br>
=end</li>
</ul>
Ruby master - Bug #2495 (Closed): Matrix: Vector#each2 should check its argument
https://bugs.ruby-lang.org/issues/2495
2009-12-19T10:35:22Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
$ rubydev -r matrix -e 'p Vector[*1..4].each2(nil){|x, y| p "#{x}, #{y}"}'<br>
/usr/local/rubydev/lib/ruby/1.9.1/matrix.rb:1149:in <code>each2': undefined method </code>size' for nil:NilClass (NoMethodError)</p>
<p>$ rubydev -r matrix -e 'p Vector[*1..4].each2(42){|x, y| p "#{x}, #{y}"}'<br>
/usr/local/rubydev/lib/ruby/1.9.1/matrix.rb:1149:in <code>each2': Vector dimension mismatch (ExceptionForMatrix::ErrDimensionMismatch) from -e:1:in </code>'</p>
<p>$ rubydev -r matrix -e 'p Vector[*1..8].each2(42){|x, y| p "#{x}, #{y}"}'<br>
"1, 0"<br>
"2, 1"<br>
"3, 0"<br>
"4, 1"<br>
"5, 0"<br>
"6, 1"<br>
"7, 0"<br>
"8, 0"</p>
<p>(or vice versa, if on a 32 bit platform)<br>
=end</p>
Ruby master - Bug #2365 (Closed): Matrix: poor handling of coercion errors [patch]
https://bugs.ruby-lang.org/issues/2365
2009-11-14T10:35:04Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
rubydev -r matrix -e 'p Matrix.I(2) - nil'<br>
/usr/local/rubydev/lib/ruby/1.9.1/matrix.rb:533:in <code>-': undefined method </code>coerce' for nil:NilClass (NoMethodError)<br>
from -e:1:in `'</p>
<p>Expected:<br>
some_where_in_the/matrix.rb:in <code>-': nil can't be coerced into Matrix (TypeError) from -e:1:in </code>'</p>
<p>Same situation with Vector.</p>
<p>I'd be grateful if you could confirm the attached patch is ok.<br>
=end</p>
Ruby master - Bug #2330 (Closed): Non systematic segmentation fault with autoload rubyspec
https://bugs.ruby-lang.org/issues/2330
2009-11-04T14:36:10Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Starting from r25601, the following rubyspec will crash about half of the time (just repeat a couple of times):</p>
<p>$ mspec -t rubydev core/kernel/autoload_spec.rb<br>
ruby 1.9.2dev (2009-11-04 trunk 25641) [x86_64-darwin10.0.0]<br>
.........../Users/work/mspec/lib/mspec/mocks/proxy.rb:8: [BUG] Segmentation fault<br>
ruby 1.9.2dev (2009-11-04 trunk 25641) [x86_64-darwin10.0.0]</p>
<p>-- control frame ----------<br>
c:0036 p:0024 s:0121 b:0121 l:000120 d:000120 METHOD /Users/work/mspec/lib/mspec/mocks/proxy.rb:8<br>
c:0035 p:---- s:0115 b:0115 l:000114 d:000114 FINISH<br>
c:0034 p:---- s:0113 b:0113 l:000112 d:000112 CFUNC :autoload<br>
c:0033 p:0057 s:0108 b:0108 l:000208 d:000107 BLOCK /Users/work/ruby/dev/spec/rubyspec/core/kernel/autoload_spec.rb:105<br>
c:0032 p:---- s:0105 b:0105 l:000104 d:000104 FINISH<br>
c:0031 p:---- s:0103 b:0103 l:000102 d:000102 CFUNC :instance_eval<br>
c:0030 p:0017 s:0100 b:0100 l:000099 d:000099 METHOD /Users/work/mspec/lib/mspec/runner/mspec.rb:67<br>
c:0029 p:0021 s:0094 b:0094 l:000081 d:000093 BLOCK /Users/work/mspec/lib/mspec/runner/context.rb:135<br>
c:0028 p:---- s:0091 b:0091 l:000090 d:000090 FINISH<br>
c:0027 p:---- s:0089 b:0089 l:000084 d:000088 IFUNC :instance_variable_get<br>
c:0026 p:---- s:0087 b:0087 l:000086 d:000086 CFUNC :each<br>
c:0025 p:---- s:0085 b:0085 l:000084 d:000084 CFUNC :all?<br>
c:0024 p:0053 s:0082 b:0082 l:000081 d:000081 METHOD /Users/work/mspec/lib/mspec/runner/context.rb:135<br>
c:0023 p:0101 s:0076 b:0076 l:000065 d:000075 BLOCK /Users/work/mspec/lib/mspec/runner/context.rb:163<br>
c:0022 p:---- s:0071 b:0071 l:000070 d:000070 FINISH<br>
c:0021 p:---- s:0069 b:0069 l:000068 d:000068 CFUNC :each<br>
c:0020 p:0127 s:0066 b:0066 l:000065 d:000065 METHOD /Users/work/mspec/lib/mspec/runner/context.rb:155<br>
c:0019 p:0109 s:0063 b:0063 l:000062 d:000062 METHOD /Users/work/mspec/lib/mspec/runner/mspec.rb:36<br>
c:0018 p:0029 s:0056 b:0056 l:000055 d:000055 METHOD /Users/work/mspec/lib/mspec/runner/object.rb:11<br>
c:0017 p:0167 s:0049 b:0049 l:000208 d:000208 TOP /Users/work/ruby/dev/spec/rubyspec/core/kernel/autoload_spec.rb:69<br>
c:0016 p:---- s:0047 b:0047 l:000046 d:000046 FINISH<br>
</p>
<p>mspec version: 1.5.12<br>
rubyspec: current<br>
=end</p>
Ruby master - Bug #2311 (Closed): [BUG] cfp consistency error - send
https://bugs.ruby-lang.org/issues/2311
2009-10-30T12:15:55Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Following r25521:</p>
<p>$rubydev -e '<br>
class X<br>
def method_missing(s); end<br>
end<br>
X.new.foo(:bar) rescue nil<br>
puts "hello"<br>
'</p>
<p>Generates<br>
-e:0:in <code>method_missing': wrong number of arguments (2 for 1) (ArgumentError) from -e:5:in </code>'<br>
Instead of "hello"</p>
<p>$ mspec core/file/stat/directory_spec.rb -t rubydev<br>
crashes ruby with [BUG] cfp consistency error - send<br>
=end</p>
Ruby master - Bug #2224 (Closed): lib/delegate: operator delegation
https://bugs.ruby-lang.org/issues/2224
2009-10-17T13:15:20Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
The operators ==, =~, !~ are forwarded by Delegate. I presume the operators != and ~, new in 1.9, have simply been forgotten?</p>
<p>As for eql? and hash, this is probably intentional. I am still curious as to why, since this can yield surprising results (at least to me):</p>
<p>a = "foo"<br>
a1 = SimpleDelegator.new(a)<br>
a2 = a1.dup<br>
h = {}<br>
h[a] = :bar<br>
h[a1] = :bar<br>
h[a2] = :bar<br>
h # ==> {"foo"=>:bar, "foo"=>:bar, "foo"=>:bar}<br>
=end</p>
Ruby master - Bug #2223 (Closed): lib/delegate: security model?
https://bugs.ruby-lang.org/issues/2223
2009-10-17T12:39:33Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Take the following code:</p>
<p>require 'delegate'<br>
cat = "cat"<br>
dog = SimpleDelegator.new("dog")</p>
<p>cat.untrust<br>
dog.untrust</p>
<p>lambda {$SAFE = 4; cat.upcase!}.call # ==> "CAT"<br>
lambda {$SAFE = 4; dog.upcase!}.call # ==> Security Error</p>
<p>Is that expected?</p>
<p>Maybe #trust, #untrust, #taint and #untaint should both call 'super' and forward the call to <strong>getobj</strong>?</p>
<p>I'm even less sure as to what to do with #tainted? and #untrusted? for mixed cases (i.e. when self and <strong>getobj</strong> have different taintedness/trust). Disallow these cases? return "super || <strong>getobj</strong>.tainted?" ?<br>
=end</p>
Ruby master - Bug #2222 (Closed): Regex creation error in safe mode
https://bugs.ruby-lang.org/issues/2222
2009-10-17T11:58:25Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
$ ruby -e '$SAFE=4; /#{}/o'<br>
-e:1:in `': Insecure: can't modify array (SecurityError)</p>
<p>Fairly recent since error not present in ruby 1.9.2dev (2009-08-30 trunk 24705)<br>
=end</p>
Ruby master - Bug #2199 (Closed): Object#method should call respond_to_missing?(sym, true)
https://bugs.ruby-lang.org/issues/2199
2009-10-13T14:16:43Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Is there any reason I'm missing?</p>
<p>class A<br>
def respond_to_missing?(method, private = false)<br>
method == :is_private && private<br>
end</p>
<pre><code> def is_private2
end
private :is_private2
</code></pre>
<p>end</p>
<p>A.new.method(:is_private2) # ==> #<Method: A#is_private2>...<br>
A.new.method(:is_private) # ==> NameError: undefined method <code>is_private' for class </code>A'</p>
<p>If not:</p>
<p>diff --git a/proc.c b/proc.c<br>
index 5ed3c01..b7c632c 100644<br>
--- a/proc.c<br>
+++ b/proc.c<br>
@@ -902,7 +902,7 @@ mnew(VALUE klass, VALUE obj, ID id, VALUE mclass, int scope)<br>
VALUE sym = ID2SYM(id);</p>
<pre><code> if (obj != Qundef && !rb_method_basic_definition_p(klass, rmiss)) {
</code></pre>
<ul>
<li>
<pre><code> if (RTEST(rb_funcall(obj, rmiss, 1, sym))) {
</code></pre>
</li>
</ul>
<ul>
<li>
<pre><code> if (RTEST(rb_funcall(obj, rmiss, 2, sym, Qtrue))) {
def = ALLOC(rb_method_definition_t);
def->type = VM_METHOD_TYPE_MISSING;
def->original_id = id;
</code></pre>
</li>
</ul>
<p>=end</p>
Ruby master - Bug #2189 (Closed): Math.atanh(1) & Math.atanh(-1) should not raise an error
https://bugs.ruby-lang.org/issues/2189
2009-10-10T14:53:28Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Regression caught by RubySpec.</p>
<p>$ rubydev -v -e 'p Math.atanh(1)'<br>
ruby 1.9.2dev (2009-10-09 trunk 25274) [x86_64-darwin10.0.0]<br>
-e:1:in <code>atanh': Numerical argument out of domain - atanh (Errno::EDOM) from -e:1:in </code>'<br>
$ ruby187 -v -e 'p Math.atanh(1)'<br>
ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0]<br>
Infinity</p>
<p>Fixed in r25279<br>
=end</p>
Ruby master - Bug #2140 (Closed): Bignum#** broken by lib/mathn
https://bugs.ruby-lang.org/issues/2140
2009-09-24T09:37:35Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
ruby -r mathn -e 'p (1<<66)**2'<br>
/usr/local/ruby19/lib/ruby/1.9.1/mathn.rb:50:in <code>**': undefined method </code>power!' for 73786976294838206464:Bignum (NoMethodError)<br>
from -e:1:in `'</p>
<p>Fixed in r25067<br>
=end</p>
Ruby master - Bug #1666 (Closed): Confusion in documentation for lines vs each_line, etc...
https://bugs.ruby-lang.org/issues/1666
2009-06-20T21:44:22Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Currently, IO#lines is defined as "to_enum(:each_line, *args)" and thus will ignore a block if one is given.<br>
On the other hand, String#lines and String#each_line are aliases, and thus will both execute the block, if one given. The same is true for StringIO#lines and StringIO#each_line.</p>
<p>The same distinction exist in IO for #bytes vs #each_byte, #chars vs #each_char, while these pairs are aliases in String and StringIO.</p>
<p>To add to the confusion, the documentation is different for String#lines vs String#each_line, #bytes vs #each_byte, #chars vs #each_char (although they are aliases). StringIO#bytes, #lines & #chars are not documented at all.</p>
<p>So either:</p>
<ol>
<li>there should not be a distinction (and IO's implementation and doc should be changed to reflect that)<br>
or 2) the distinction is intentional (and String + StringIO's implementation should be changed to relect that)<br>
or 3) there is a compelling reason why the behavior in IO should be different than in String and StringIO and that should be spelled out in the doc.</li>
</ol>
<p>In all cases, the documentation for String should be cleaned up; for example String#each_char doesn't state that an enumerator is returned if no block is given (contrary to the doc for String#chars) and the examples are wrong since they use #each (which no longer exists) instead of #each_char.</p>
<p>Finally, the pair #codepoints and #each_codepoint is in a similar mismatch of documentation in String. I'll post a separate feature request to add IO#codepoints, etc...<br>
=end</p>
Ruby master - Bug #1665 (Closed): Enumerable#reverse_each, #entries, #to_a documentation [patch]
https://bugs.ruby-lang.org/issues/1665
2009-06-20T20:40:16Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
The following are missing from the 1.8.7 release News:<br>
Enumerable#reverse_each (new method)<br>
Enumerable#to_a, #entries (takes optional arguments)</p>
<p>Since the 1.9 release News refer to the 1.8.7 news, this fixes both 1.8.7 and 1.9 release news.</p>
<p>Moreover the documentation for Enumerable#to_a, #entries needs to be updated in both the 1.8.7 and 1.9 releases (patches for both included).<br>
=end</p>
Ruby master - Bug #1532 (Closed): Improved matrix.rb [patch]
https://bugs.ruby-lang.org/issues/1532
2009-05-29T04:18:55Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
The fact that the 'matrix' library is included in Ruby is very helpful.<br>
There are currently some open bugs, and some improvements could make it easier to use.</p>
<p>Propositions:</p>
<ol>
<li>Matrix#trace should raise an ErrDimensionMismatch if the matrix is not square</li>
</ol>
<p>Mathematically speaking, the trace is only defined for square matrices (ref: wikipedia, mathworld)<br>
Currently, Matrix[[1,2]].trace raises a NoMethodError: undefined method `[]' for nil:NilClass<br>
Note that Matrix[[1,2]].transpose.trace returns 1, although in mathematically, trace(M) = trace(transpose(M))</p>
<p>Raising an ErrDimensionMismatch would bring #trace in line with #inverse</p>
<ol start="2">
<li>Matrix creation methods should perform checks and conversion so that values are stored as an Array of Arrays.</li>
</ol>
<p>Currently, no checking is done, so the following will all be constructed without an error or a warning:<br>
Matrix[:hello]<br>
Matrix[nil]<br>
Matrix[4], etc...</p>
<p>Later on, confusing results or strange errors will happen. E.g.:<br>
Matrix[42].transpose # ==> Matrix[[42], [0], [0], [0]]</p>
<p>A TypeError should be raised if the argument is not convertible to an Array of Arrays.</p>
<p>Moreover, non arrays that should be converted using :to_ary, to be consistent<br>
with the builtin library methods that accept array arguments (e.g. Array#transpose)</p>
<p>Finally, conversion from Vector to arrays should be always be performed. Currently,<br>
a = Matrix[[1,2],[3,4]] # => Matrix[[1, 2], [3, 4]]<br>
b = Matrix.rows([a.row(0), a.row(1)]) # => Matrix[Vector[1, 2], Vector[3, 4]]<br>
a == b # => false<br>
It would be more useful, intuitive and mathematically correct if a == b and b.to_s == "Matrix[[1, 2], [3, 4]]"</p>
<p>The same is true for Vector creation methods. For example currently:<br>
Vector.elements(42, false).size # ==> 4<br>
Vector.elements(Vector[1,2,3]) == Vector.elements([1,2,3]) # ==> false<br>
It would be more useful, intuitive and correct if the first example raises an error and the second returns true</p>
<ol start="3">
<li>Matrix creators should enforce that a matrix is rectangular.</li>
</ol>
<p>Currently, a matrix with irregular rows can be created, e.g. x = Matrix[[1,2],[3]].<br>
Mathematically speaking, that is not a matrix.<br>
Basically none of the Matrix methods are of any use for non-rectangular matrices.<br>
Moreover, many strange errors can occur later on. For example, x.inverse will<br>
raise a "NoMethodError: undefined method `*' for nil:NilClass"</p>
<p>It would be helpful to catch these cases at creation time.<br>
Many creation methods don't have to make any extra checks (e.g. Matrix.scalar), and<br>
all methods of Matrix can bypass this extra check when they have created the arrays themselves<br>
(e.g. Matrix#*). There would be a small cost for creation using Matrix.[] and Matrix.rows,<br>
although it is in O(rows) while most other operations are usually in O(rows x columns),<br>
so the performance difference would be minimal.</p>
<ol start="4">
<li>Matrix should deal with empty matrices.</li>
</ol>
<p>Currently, empty matrices like Matrix[] cause problem.<br>
For example Matrix[].determinant raises an error, so does Matrix[] * Matrix[].</p>
<p>Moreover, if h = Matrix[[], []], then currently h.transpose.transpose != h</p>
<p>While an alternative would be to raise and error, the best solution is to handle<br>
empty matrices properly, both 0x0, 0xn and nx0, as does MatLab, GNU Octave, etc...<br>
See doc and references to the literature in:<br>
<a href="http://www.gnu.org/software/octave/doc/interpreter/Empty-Matrices.html" class="external">http://www.gnu.org/software/octave/doc/interpreter/Empty-Matrices.html</a></p>
<ol start="5">
<li>Out of bound indices should be dealt with.</li>
</ol>
<p>a) Matrix#[row,col] should behave in a consisten way if either row or col is out of bounds.<br>
Currently it returns nil vs raises an obscure error (See redmine #1518.)</p>
<p>b) Matrix[[1]].row(2) raises an obscure error, while Matrix[[1]].column(2) returns Vector[nil, nil]</p>
<p>c) In a similar vein, Matrix[[1]].minor(2..2,1..1) currently raises an error but not<br>
Matrix[[1]].minor(1..1,2..2)</p>
<p>Solutions:<br>
a) To be consistent with array lookup using [], Matrix#[] should return nil for out of bounds elements.<br>
A #fetch method could be added, but the fact that matrices normally won't contain nil or false<br>
makes it easy to deal with out of bounds references, e.g. m[r, c] || 0</p>
<p>b) Contrary to nil, it is not easy nor useful to deal with Vector[nil, nil, ...].<br>
#row, and #column could raise an IndexError, but it is more useful and<br>
more coherent with Array#at, etc... to return nil.</p>
<p>c) The same way Matrix#row and #col can be related to Array#at,<br>
Matrix#minor should have similar semantics to Array#slice. If either starting point<br>
is out of bounds, nil is returned. Otherwise a Matrix is returned, although it can<br>
be smaller than what was requested. This is similar to<br>
[:a, :b].slice(3..10) # => nil<br>
[:a, :b].slice(2..10) # => []<br>
[:a, :b].slice(1..10) # => [:b]<br>
Matrix[[1], [2]].minor(0..10, 2..10) # => nil<br>
Matrix[[1], [2]].minor(0..10, 1..10) # => Matrix[[], []]<br>
Matrix[[1], [2]].minor(1..10, 0..10) # => Matrix[[2]]</p>
<ol start="6">
<li>Matrix#collect, Vector#collect, #collect2, #map2 should return enumerators if no block is given</li>
</ol>
<p>This would be more useful and is consistent with Array#each, etc...</p>
<ol start="7">
<li>Matrix#hash should have less collisions</li>
</ol>
<p>Currently, the following matrices have the same hash:<br>
Matrix[]<br>
Matrix[[0,0], [0,0]]<br>
Matrix[[1,0], [0,1]]<br>
Matrix[[42,42], [666,666]]<br>
Matrix[[1,2,3,4], [5,6,1,2], [3,4,5,6]]</p>
<p>Ideally, these should have different hashes, since they are different matrices.</p>
<ol start="8">
<li>Matrix#compare_by_row_vectors, Vector#compare_by and Vector#init_elements should be made private or disappear.</li>
</ol>
<p>As per the documentation, these are not meant to be used.<br>
As such it would be best if they didn't appear in the list of methods.</p>
<p>The attached patch addresses all these issues.</p>
<p>Moreover, it addresses all matrix-related issues I could find on redmine:<br>
<a href="http://redmine.ruby-lang.org/issues/show/1020" class="external">http://redmine.ruby-lang.org/issues/show/1020</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1515" class="external">http://redmine.ruby-lang.org/issues/show/1515</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1516" class="external">http://redmine.ruby-lang.org/issues/show/1516</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1517" class="external">http://redmine.ruby-lang.org/issues/show/1517</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1518" class="external">http://redmine.ruby-lang.org/issues/show/1518</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1526" class="external">http://redmine.ruby-lang.org/issues/show/1526</a><br>
<a href="http://redmine.ruby-lang.org/issues/show/1531" class="external">http://redmine.ruby-lang.org/issues/show/1531</a></p>
<p>Also fixed a bug with #determinant and #determinant_e that would raise an error for some matrices<br>
(for instance any square matrix with m[0][0] == 0, e.g. Matrix[[0,1],[2,3]].determinant # => error raised)</p>
<p>Finally, the following methods are performing faster:<br>
Matrix#collect<br>
Matrix#transpose<br>
Matrix#==<br>
Matrix#eql?<br>
Matrix#hash<br>
Vector#collect<br>
Vector#map2</p>
<p>Note that the branch 'runpaint' of rubyspecs has specs to this patch.<br>
=end</p>
Ruby master - Bug #1531 (Closed): Matrix#determinant fails on some matrices
https://bugs.ruby-lang.org/issues/1531
2009-05-29T04:17:19Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
ruby1.9 -r matrix -e 'Matrix[[0,1],[1,0]].determinant'<br>
/usr/local/ruby191/lib/ruby/1.9.1/matrix.rb:685:in <code>block (2 levels) in determinant': undefined method </code>+' for nil:NilClass (NoMethodError)<br>
from /usr/local/ruby191/lib/ruby/1.9.1/matrix.rb:684:in <code>loop' from /usr/local/ruby191/lib/ruby/1.9.1/matrix.rb:684:in </code>block in determinant'<br>
from /usr/local/ruby191/lib/ruby/1.9.1/matrix.rb:681:in <code>loop' from /usr/local/ruby191/lib/ruby/1.9.1/matrix.rb:681:in </code>determinant'<br>
from -e:1:in `'</p>
<p>Same with determinant_e.</p>
<p>To fix: gsub('ii','i') in matrix.rb<br>
=end</p>
Ruby master - Bug #1385 (Closed): Wonderful undocumented feature in Ruby 1.8.7 & 1.9
https://bugs.ruby-lang.org/issues/1385
2009-04-17T13:40:20Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
6 months ago, I begged for a natural way to construct a Hash from key-value pairs: <a href="http://redmine.ruby-lang.org/issues/show/666" class="external">http://redmine.ruby-lang.org/issues/show/666</a><br>
Maybe because of a lack of superstitious devil worshippers, there was no additional comment on this issue # 666, which seems even stranger after a discovery I made by pure random luck (hey, my last name is not Lafortune for nothing!). It appears there <em>already is</em> a way, using Hash::[]</p>
<p>Example:<br>
Hash[[[:i_like, :ruby], [:hello, "world!"], [:answer, 42]]]<br>
=> {:i_like => :ruby, :hello => "world!", :answer => 42}</p>
<p>Wouhou, exciting! This works in both Ruby 1.8.7 and 1.9.1, but it is not documented <em>anywhere</em> where it should:<br>
<a href="http://www.ruby-doc.org/core-1.9/classes/Hash.html#M002653" class="external">http://www.ruby-doc.org/core-1.9/classes/Hash.html#M002653</a><br>
<a href="http://www.ruby-doc.org/core-1.8.7/classes/Hash.html#M000148" class="external">http://www.ruby-doc.org/core-1.8.7/classes/Hash.html#M000148</a><br>
<a href="http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS" class="external">http://svn.ruby-lang.org/repos/ruby/tags/v1_8_7/NEWS</a><br>
<a href="http://eigenclass.org/hiki/Changes+in+Ruby+1.9" class="external">http://eigenclass.org/hiki/Changes+in+Ruby+1.9</a><br>
The Ruby Programming Language (section 9.5.3.1)</p>
<p>At first I thought maybe my satanic incantations were to thank for this hidden feature, but the huge 1.9 changelog reads:</p>
<p>Fri Oct 26 01:48:28 2007 Yukihiro Matsumoto <a href="mailto:matz@ruby-lang.org" class="email">matz@ruby-lang.org</a></p>
<pre><code>* hash.c (rb_hash_s_create): Hash#[] now takes assocs as source of
hash conversion.
</code></pre>
<p>So, thank you Matz!</p>
<p>I'm thus filing a bug report for the missing documentation, praying that the reason it is not documented is a simple oversight and that we can officially count on this for the future. In any case I eagerly included this cool feature in my backports for 1.8.x (<a href="http://github.com/marcandre/backports" class="external">http://github.com/marcandre/backports</a> ) since I still don't get the point of 1.8.7 (<a href="http://blog.marc-andre.ca/2009/04/whats-point-of-ruby-187.html" class="external">http://blog.marc-andre.ca/2009/04/whats-point-of-ruby-187.html</a> ) and I'll use Hash::[] until we get (one day maybe) my dreamed Enumerable#to_hash which I still favor.</p>
<p>I'd propose an updated doc similar to the following:</p>
<p>/*</p>
<ul>
<li>call-seq:</li>
<li>
<pre><code>Hash[ key, value, ... ] => hash
</code></pre>
</li>
<li>
<pre><code>Hash[ [ [key, value], ... ] ] => hash
</code></pre>
</li>
<li>
<pre><code>Hash[ object ] => hash
</code></pre>
</li>
<li>
<li>Creates a new hash populated with the given objects. Equivalent to</li>
<li>the literal <code>{ <i>key</i> => <i>value</i>, ... }</code>. In the first</li>
<li>form, keys and values occur in pairs, so there must be an even number of arguments.</li>
<li>The second and third form take a single argument which is either</li>
<li>an array of key-value pairs or an object convertible to a hash.</li>
<li>
<li>
<pre><code>Hash["a", 100, "b", 200] #=> {"a"=>100, "b"=>200}
</code></pre>
</li>
<li>
<pre><code>Hash[ [ ["a" => 100], ["b" => 200] ] ] #=> {"a"=>100, "b"=>200}
</code></pre>
</li>
<li>
<pre><code>Hash["a" => 100, "b" => 200] #=> {"a"=>100, "b"=>200}
</code></pre>
</li>
<li>
<pre><code>{"a" => 100, "b" => 200} #=> {"a"=>100, "b"=>200}
</code></pre>
</li>
</ul>
<p>*/</p>
<p>Is it just me or is the last example not quite insightful? In any case, if a different text than mine is used, note that the present version still mentions the old 1.8 syntax: <code>{ <i>key</i>, <i>value</i>, ... }</code></p>
<p>Is there a prize for the most long-winded bug report just for the documentation? To be a sure winner, I'll add that I find interesting that my infamous feature request # 666 would make the second form merge naturally into the third, since an array of key-value pairs would be convertible to a hash!</p>
<p>Thank you for your attention,</p>
<p>Marc-André Lafortune<br>
=end</p>
Ruby master - Bug #1165 (Closed): Range.eql? and Range.== bug with subclasses
https://bugs.ruby-lang.org/issues/1165
2009-02-17T05:10:45Z
marcandre (Marc-Andre Lafortune)
marcandre-ruby-core@marc-andre.ca
<p>=begin<br>
Contrary to the documentation (and to what I would expect):</p>
<p>class TrivialRangeSubclass < Range<br>
end</p>
<p>TrivialRangeSubclass.new(0,1) == Range.new(0,1) # ==> false</p>
<p>This bug is present in the current versions of ruby 1.8.7 and 1.9.1. As a matter of curiosity, I checked both JRuby (1.1.6) and rubinius (0.10.0) and they both return true (as they should).</p>
<p>Although I'm not familiar with the source code, it seams like a simple change, so I've included a patch for the 1.9.1 version. I hope I did things correctly! Changelog could read like:</p>
<p>Mon Feb 16 14:35:35 2009 Marc-Andre Lafortune <a href="mailto:ruby-lang@marc-andre.ca" class="email">ruby-lang@marc-andre.ca</a></p>
<pre><code>* range.c (range_eql, range_eq): fixed equality to work for
subclasses of Range.
* test/ruby/test_range.rb: add assertions for above.
</code></pre>
<p>Thank you!<br>
=end</p>