Ruby Issue Tracking System: Issueshttps://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112016-02-24T04:29:50ZRuby Issue Tracking System
Redmine Ruby master - Bug #12106 (Closed): Behavior of double splatting of hashes with non symbol key is ...https://redmine.ruby-lang.org/issues/121062016-02-24T04:29:50Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>When doing double splatting with hash with non symbols keys you get different behaviors according to the position of the hash been splatted:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="p">{</span><span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># Works fine</span>
<span class="p">{</span><span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">}}</span> <span class="c1"># Works fine</span>
<span class="p">{</span><span class="mi">3</span> <span class="o">=></span> <span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># Works fine</span>
<span class="p">{</span><span class="o">**</span><span class="p">{},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># Works fine</span>
<span class="p">{</span><span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="p">{</span><span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">}}</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="p">{</span><span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="p">{</span><span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">}}</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
</code></pre>
<p>Same thing happens when you double splat inside a message send:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="nb">puts</span><span class="p">(</span><span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># Works fine</span>
<span class="nb">puts</span><span class="p">(</span><span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">})</span> <span class="c1"># Works fine</span>
<span class="nb">puts</span><span class="p">(</span><span class="mi">3</span> <span class="o">=></span> <span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># Works fine</span>
<span class="nb">puts</span><span class="p">(</span><span class="o">**</span><span class="p">{},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># Works fine</span>
<span class="nb">puts</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="ss">b: </span><span class="mi">1</span><span class="p">},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="mi">1</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="nb">puts</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">})</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="nb">puts</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">},</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
<span class="nb">puts</span><span class="p">(</span><span class="o">**</span><span class="p">{</span><span class="ss">c: </span><span class="mi">4</span><span class="p">},</span> <span class="ss">a: </span><span class="mi">3</span><span class="p">,</span> <span class="o">**</span><span class="p">{</span><span class="s1">'b'</span> <span class="o">=></span> <span class="mi">1</span><span class="p">})</span> <span class="c1"># TypeError: wrong argument type Fixnum (expected Symbol)</span>
</code></pre>
<p>What's basically going on is this: you can double splat hashes with no symbol keys all you want, only if the first value of the hash is a regular key (symbol or not) and not a splatted hash, or also a double splatted empty hash.</p>
<p>It feels strange that building the same hash in different orders yields so different behaviors.<br>
Anyhow, I personally feel it should be a bug if you cannot splat a hash with no symbol keys into another one, whichever are the remaining values of the hash.</p> Ruby master - Bug #11284 (Rejected): String#upcase and String#downcase don't work for accented ch...https://redmine.ruby-lang.org/issues/112842015-06-18T20:20:12Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>Many accented and other non-english characters fails to upcase/downcase properly.<br>
Accented characters is the most common are the ones I keep stumbling upon,, but probably other germanic/nordic characters I'm not aware of have the same problems.</p>
<p>For example:</p>
<pre><code>"Hola, ¿Cómo estás?".upcase # returns "HOLA, ¿CóMO ESTáS?"
"CONFIANÇA".downcase # returns "confianÇa"
"Un moment s'il vous plaît".upcase # returns "UN MOMENT S'IL VOUS PLAîT"
</code></pre> Ruby master - Bug #11120 (Closed): Unexpected behavior when mixing Module#prepend with method ali...https://redmine.ruby-lang.org/issues/111202015-05-04T16:57:03Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>I'm not completely sure myself if this should be considered a bug, but at least it should be up for discussion.</p>
<p>I stumbled upon this behavior when migrating some code using alias chains to Module#prepend.<br>
Consider the following code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="c1"># thingy.rb</span>
<span class="k">class</span> <span class="nc">Thingy</span>
<span class="k">def</span> <span class="nf">thingy</span>
<span class="nb">puts</span> <span class="s2">"thingy"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="c1"># thingy_with_foo.rb</span>
<span class="k">module</span> <span class="nn">ThingyWithFoo</span>
<span class="k">def</span> <span class="nf">thingy</span>
<span class="nb">puts</span> <span class="s2">"thingy with foo"</span>
<span class="k">super</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="no">Thingy</span><span class="p">.</span><span class="nf">prepend</span><span class="p">(</span><span class="no">ThingyWithFoo</span><span class="p">)</span>
<span class="c1"># thingy_with_bar.rb</span>
<span class="k">class</span> <span class="nc">Thingy</span>
<span class="kp">alias_method</span> <span class="ss">:thingy_without_bar</span><span class="p">,</span> <span class="ss">:thingy</span> <span class="c1"># Wont't alias create an alias for Thingy#thingy but ThingyWithFoo#thingy instead</span>
<span class="k">def</span> <span class="nf">thingy_with_bar</span>
<span class="nb">puts</span> <span class="s2">"thingy with bar"</span>
<span class="n">thingy_without_bar</span> <span class="c1"># Expected to call original Thingy#thingy method but will call prepended method instead</span>
<span class="k">end</span>
<span class="kp">alias_method</span> <span class="ss">:thingy</span><span class="p">,</span> <span class="ss">:thingy_with_bar</span>
<span class="k">end</span>
<span class="c1"># some_file.rb</span>
<span class="no">Thingy</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">thingy</span> <span class="c1"># raises: stack level too deep (SystemStackError))</span>
</code></pre>
<p>In a nutshell when calling <code>super</code> from <code>ThingyWithFoo#foo</code> it will call <code>thingy_with_bar</code> method, and this method will call back to <code>ThingyWithFoo#foo</code> by invoking <code>thingy_without_bar</code>, thus producing an endless loop.</p>
<p>This situation arises because <code>alias_method</code> is producing an alias not for the Thingy#thingy method the but for the upper method from <code>ThingyWithFoo</code> instead. May be this behavior could be considered correct, I'm still not sure, but it will probably became a problem for source code migrating from alias chains to use <code>Modue#prepend</code>, specially when other active gems could potentially still be using alias chains themselves without the user knowledge.</p> Ruby master - Bug #10818 (Closed): Extrange behaviour when apliying a refinement inside evalhttps://redmine.ruby-lang.org/issues/108182015-02-02T08:19:47Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>When you activate a refinement inside an a string using <code>eval</code> with a binding, the refinement is sill active the next time you call <code>eval</code> with the same binding.<br>
Strangely enough, this will only happen if there is an assignment at the code evaluated the first time. If you delete the assignment everything works as expected.</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">M</span>
<span class="n">refine</span> <span class="no">String</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">foobar</span><span class="p">;</span> <span class="nb">puts</span> <span class="s1">'foobar'</span><span class="p">;</span> <span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">some_binding</span> <span class="o">=</span> <span class="k">class</span> <span class="nc">A</span><span class="p">;</span> <span class="nb">binding</span><span class="p">;</span> <span class="k">end</span>
<span class="n">str1</span> <span class="o">=</span> <span class="o"><<</span><span class="no">EOF</span><span class="sh">
a = 'something' # Without this everything works as expected
using M
'str'.foobar # Works fine
</span><span class="no">EOF</span>
<span class="n">str2</span> <span class="o">=</span> <span class="o"><<</span><span class="no">EOF</span><span class="sh">
'str'.foobar # This time should fail but it doesn't
</span><span class="no">EOF</span>
<span class="nb">eval</span> <span class="n">str1</span><span class="p">,</span> <span class="n">some_binding</span>
<span class="nb">eval</span> <span class="n">str2</span><span class="p">,</span> <span class="n">some_binding</span>
</code></pre>
<p>Acording to the <a href="https://bugs.ruby-lang.org/projects/ruby-trunk/wiki/RefinementsSpec" class="external">RefinmentsSpec</a>: "when main.using is invoked in a string given as the first argument of Kernel#eval, Kernel#instance_eval, or Module#module_eval, the end of the scope is the end of the string."</p>
<p>Which contradicts with this code's behavior.</p> Ruby master - Bug #10812 (Closed): Object#respond_to? doesn't acknowledge active refinementshttps://redmine.ruby-lang.org/issues/108122015-02-01T08:27:24Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>Object#respond_to? seems to ignore active refinements.</p>
<p>Take for instance the following code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">module</span> <span class="nn">R1</span>
<span class="n">refine</span> <span class="no">String</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">foobar</span>
<span class="s1">'foobar'</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="nb">puts</span> <span class="s1">'string'</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="ss">:foobar</span><span class="p">)</span> <span class="c1"># Returns false</span>
<span class="n">using</span> <span class="no">R1</span>
<span class="nb">puts</span> <span class="s1">'string'</span><span class="p">.</span><span class="nf">foobar</span> <span class="c1"># Returns 'foobar'</span>
<span class="nb">puts</span> <span class="s1">'string'</span><span class="p">.</span><span class="nf">respond_to?</span><span class="p">(</span><span class="ss">:foobar</span><span class="p">)</span> <span class="c1"># Is still false</span>
</code></pre>
<p>Also seems to equally fail at ruby 2.1.5</p> Backport200 - Backport #8040 (Closed): Unexpect behavior when using keyword argumentshttps://redmine.ruby-lang.org/issues/80402013-03-08T03:39:17Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>=begin<br>
There is an odd behavior when calling methods with the new keyword arguments syntax, when you have a method defined with mandatory arguments that also takes options, like this:</p>
<p>def foo value, **keywords<br>
puts [value,keywords].inspect<br>
end</p>
<p>foo("somthing") #This works<br>
foo("somthing", key: 'value') #This also works</p>
<p>foo(Hash.new(something: 'else')) #This raises 'ArgumentError: wrong number of arguments (0 for 1)'</p>
<p>This feels weird regardless the fact that keyword arguments are a Hash at the bottom, since you ARE PASSING an argument.</p>
<p>Other side effect from this, is that when you call the method ((|foo|)) with a single argument, you can't anticipate how many argument you will be actually passing at runtime unless you know beforehand the argument's class.</p>
<p>What's maybe even more concerning is the fact than this happens even when you pass an argument which class derives from Hash:</p>
<p>class MyDirectory < Hash; end</p>
<p>foo(MyDirectory.new(something: 'else')) #This also raises 'ArgumentError: wrong number of arguments (0 for 1)'</p>
<p>Besides finding this behavior surprising, I think this could also possibly lead to old code been unexpectedly broken when updating old methods that takes options to the new syntax.</p>
<p>For example if you have this code:</p>
<p>def foo_with_options argument, options = {}<br>
#Do some stuff with options<br>
end</p>
<p>#And at someplace else...</p>
<p>my_hash_thingy = Hash.new<br>
foo_with_options(my_hash_thingy) #Only passing mandatory argument, with no options, works fine.</p>
<p>When updating to the new syntax:</p>
<p>def foo_with_options argument, an_option: 'value1', another_option: 'value2'<br>
#Do some stuff with options<br>
end</p>
<p>#And at someplace else...</p>
<p>my_hash_thingy = Hash.new<br>
foo_with_options(my_hash_thingy) #Only passing mandatory argument, with no options, doesn't work anymore.<br>
=end</p> Ruby master - Feature #6284 (Closed): Add composition for procshttps://redmine.ruby-lang.org/issues/62842012-04-12T15:21:25Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>It would be nice to be able to compose procs like functions in functional programming languages:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">to_camel</span> <span class="o">=</span> <span class="ss">:capitalize</span><span class="p">.</span><span class="nf">to_proc</span>
<span class="n">add_header</span> <span class="o">=</span> <span class="o">-></span><span class="n">val</span> <span class="p">{</span><span class="s2">"Title: "</span> <span class="o">+</span> <span class="n">val</span><span class="p">}</span>
<span class="n">format_as_title</span> <span class="o">=</span> <span class="n">add_header</span> <span class="o"><<</span> <span class="n">to_camel</span> <span class="o"><<</span> <span class="ss">:strip</span>
</code></pre>
<p>instead of:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">format_as_title</span> <span class="o">=</span> <span class="nb">lambda</span> <span class="p">{</span><span class="o">|</span><span class="n">val</span><span class="o">|</span> <span class="s2">"Title: "</span> <span class="o">+</span> <span class="n">val</span><span class="p">.</span><span class="nf">strip</span><span class="p">.</span><span class="nf">capitalize</span> <span class="p">}</span>
</code></pre>
<p>It's pretty easy to implement in pure ruby:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Proc</span>
<span class="k">def</span> <span class="nf"><<</span> <span class="n">block</span>
<span class="nb">proc</span> <span class="p">{</span> <span class="o">|*</span><span class="n">args</span><span class="o">|</span> <span class="nb">self</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span> <span class="n">block</span><span class="p">.</span><span class="nf">to_proc</span><span class="p">.</span><span class="nf">call</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="p">)</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre> Ruby master - Bug #6267 (Closed): Segmentation fault when exponentiating complex numberhttps://redmine.ruby-lang.org/issues/62672012-04-07T08:15:43Zpabloh (Pablo Herrero)pablodherrero@gmail.com
<p>A segfault is raised when running the following script, with any exponent greater or equal to 5:</p>
<p>require "mathn/complex"<br>
Complex(0,1)**5</p>
<p>It only seems to happen when exponentiating pure imaginary numbers and if 'mathn/coplex' is loaded, otherwise it works just fine.</p>