Ruby Issue Tracking System: Issueshttps://bugs.ruby-lang.org/https://bugs.ruby-lang.org/favicon.ico?17113305112020-05-12T17:55:30ZRuby Issue Tracking System
Redmine Ruby master - Feature #16851 (Feedback): Ruby hashing algorithm could be improved using Tabulatio...https://bugs.ruby-lang.org/issues/168512020-05-12T17:55:30Zana06 (Ana Maria Martinez Gomez)
<p>I have implemented Linear Probing and Simple tabulation in Ruby: <a href="https://github.com/Ana06/ruby/compare/master...Ana06:tabulation" class="external">https://github.com/Ana06/ruby/compare/master...Ana06:tabulation</a></p>
<p>I tested it using the following code:<br>
<a href="https://github.com/Ana06/ruby-tabulation/blob/master/benchmark_tabulation.rb" class="external">https://github.com/Ana06/ruby-tabulation/blob/master/benchmark_tabulation.rb</a><br>
It benchmarks the insertion of 600000 elements (by hashing their 64 bits ids) in an empty hash 100 times. Below are the times (in seconds) I got executing this code for different versions of the Ruby code:</p>
<ul>
<li>master (without Simple Tabulation): 29.68</li>
<li>master with Linear Probing (without Simple Tabulation): 99.76</li>
<li>master with Quadratic Probing (without Simple Tabulation): 29.97</li>
<li>master with Simple Tabulation: 15.76</li>
<li>master with Linear Probing and Simple Tabulation: 24.23</li>
<li><strong>master with Quadratic Probing and Simple Tabulation: 13.73</strong></li>
</ul>
<p><code>master</code> refers to ruby 2.8.0dev:<br>
(2020-05-07T16:22:38Z master 7ded8fd) [x86_64-linux].<br>
I tried with 8 x Intel i5-8265U.</p>
<p>Although this is just a proof of concept and not something that could be already use in production, I think it proves the potential of Simple Tabulation to improve current Ruby implementation. It may be worthwhile to explore this idea further. What do you think?</p>
<p>I did this as part of a project for my <a href="http://www.cs.columbia.edu/~andoni/advancedS20/index.html" class="external">Advanced Algorithms course</a>. For more details check the project report:<br>
<a href="https://github.com/Ana06/ruby-tabulation/blob/master/latex/RubyTabulation_Project.pdf" class="external">https://github.com/Ana06/ruby-tabulation/blob/master/latex/RubyTabulation_Project.pdf</a></p> Ruby master - Bug #16850 (Closed): Object#hash doesn't behave as documentedhttps://bugs.ruby-lang.org/issues/168502020-05-12T17:25:05Zana06 (Ana Maria Martinez Gomez)
<p>From <a href="https://ruby-doc.org/core-2.7.0/Object.html#method-i-hash" class="external">Ruby 2.7 Object class documentation</a>:</p>
<blockquote>
<p>The hash value is used along with eql? by the Hash class to determine if two objects reference the same hash key.</p>
</blockquote>
<p>From this I expect that overwritting the <code>Object#hash</code> method changes the Hashing algorithm. But this is only the case for some objets. Consider the following code:</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="k">class</span> <span class="nc">Object</span>
<span class="k">def</span> <span class="nf">hash</span>
<span class="n">i_dont_exist</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">class</span> <span class="nc">Ana</span>
<span class="k">end</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="p">{}</span>
<span class="nb">hash</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="kp">true</span>
<span class="nb">hash</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="kp">false</span>
<span class="nb">puts</span> <span class="s1">'Integers are not using the new hash method'</span>
<span class="nb">hash</span><span class="p">[</span><span class="no">Ana</span><span class="p">.</span><span class="nf">new</span><span class="p">]</span> <span class="o">=</span> <span class="kp">true</span>
<span class="nb">puts</span> <span class="s1">'this will not be executed because the class Ana uses the new hash method'</span>
</code></pre>
<p>The output of executing this code is:</p>
<pre><code>Integers are not using the new hash method
Traceback (most recent call last):
1: from a.rb:13:in `<main>'
a.rb:3:in `hash': undefined local variable or method `i_dont_exist' for #<Ana:0x000055626f0b7a30> (NameError)
</code></pre>
<p>This proves that Integer hash method is not used to determine if two objects reference the same hash key, as said in the documentation. Check the <a href="https://github.com/ruby/ruby/blob/master/hash.c#L188" class="external"><code>any_hash</code> method</a> for the other classes affected.</p>
<p>I think that either the behavior should be modified (aiming for a consistency along different classes and following the documentation) or the documentation updated.</p> Ruby master - Bug #16840 (Closed): Decrease in Hash#[]= performance with object keyshttps://bugs.ruby-lang.org/issues/168402020-05-07T18:15:09Zana06 (Ana Maria Martinez Gomez)
<p>I was playing around with Ruby hashing and I have discovered something strange/surprising.</p>
<p>The file <code>test.rb</code> looks like:</p>
<pre><code class="ruby syntaxhl" data-language="ruby">
<span class="nb">require</span> <span class="s1">'benchmark'</span>
<span class="vg">$N</span> <span class="o">=</span> <span class="mi">100000</span>
<span class="k">class</span> <span class="nc">Ana</span>
<span class="k">end</span>
<span class="n">objects</span> <span class="o">=</span> <span class="no">Array</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="vg">$N</span><span class="p">)</span> <span class="p">{</span> <span class="no">Ana</span><span class="p">.</span><span class="nf">new</span><span class="p">()</span> <span class="p">}</span>
<span class="nb">hash</span> <span class="o">=</span> <span class="p">{}</span>
<span class="nb">puts</span> <span class="no">Benchmark</span><span class="p">.</span><span class="nf">measure</span> <span class="p">{</span> <span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="p">{</span> <span class="n">objects</span><span class="p">.</span><span class="nf">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">obj</span><span class="o">|</span> <span class="nb">hash</span><span class="p">[</span><span class="n">obj</span><span class="p">]</span> <span class="o">=</span> <span class="kp">true</span> <span class="p">}</span> <span class="p">}}</span>
</code></pre>
<p>I executed <code>test.rb</code> with different Ruby versions and it takes longer with newer versions. There is 1.5 seconds difference between Ruby 2.5 and master. Is that expected? And if so, why? Those are the execution results:</p>
<pre><code>> rbenv shell 2.5.0
> ruby -v
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
> ruby test.rb
2.236504 0.003546 2.240050 ( 2.240256)
> ruby test.rb
2.247041 0.003680 2.250721 ( 2.250860)
> ruby test.rb
2.276305 0.000351 2.276656 ( 2.276829)
>·
> rbenv shell 2.6.2
> ruby -v
ruby 2.6.2p47 (2019-03-13 revision 67232) [x86_64-linux]
> ruby test.rb
2.579052 0.004181 2.583233 ( 2.583541)
> ruby test.rb
2.580179 0.000000 2.580179 ( 2.580362)
> ruby test.rb
2.646516 0.000441 2.646957 ( 2.647398)
>·
> rbenv shell 2.7.1
> ruby -v
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux]
> ruby test.rb
2.915415 0.004209 2.919624 ( 2.920206)
> ruby test.rb
2.867767 0.007511 2.875278 ( 2.875416)
> ruby test.rb
2.877741 0.000410 2.878151 ( 2.878431)
>·
> rbenv shell 2.8.0-dev
> ruby -v
ruby 2.8.0dev (2020-05-07T16:22:38Z master 7ded8fd29a) [x86_64-linux]
> ruby test.rb
3.840961 0.007852 3.848813 ( 3.849499)
> ruby test.rb
3.748391 0.007833 3.756224 ( 3.756520)
> ruby test.rb
3.686487 0.001656 3.688143 ( 3.688332)
</code></pre> Ruby master - Bug #16788 (Rejected): T_CLASS counts classes doublehttps://bugs.ruby-lang.org/issues/167882020-04-15T17:22:21Zana06 (Ana Maria Martinez Gomez)
<p>Consider the following code:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">h</span> <span class="o">=</span> <span class="p">{}</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">count_objects</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Counts: </span><span class="si">#{</span> <span class="n">h</span><span class="p">[</span><span class="ss">:T_CLASS</span><span class="p">]</span> <span class="si">}</span><span class="s2">, </span><span class="si">#{</span> <span class="n">h</span><span class="p">[</span><span class="ss">:T_ICLASS</span><span class="p">]</span> <span class="si">}</span><span class="s2">"</span>
<span class="n">objects</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">classes</span> <span class="o">=</span> <span class="p">[]</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">each_object</span><span class="p">(</span><span class="no">Object</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">objects</span> <span class="o"><<</span> <span class="n">x</span><span class="p">}</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">each_object</span><span class="p">(</span><span class="no">Class</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">classes</span> <span class="o"><<</span> <span class="n">x</span><span class="p">}</span>
<span class="k">class</span> <span class="nc">Test</span>
<span class="k">end</span>
<span class="n">objects2</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">classes2</span> <span class="o">=</span> <span class="p">[]</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">each_object</span><span class="p">(</span><span class="no">Object</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">objects2</span> <span class="o"><<</span> <span class="n">x</span><span class="p">}</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">each_object</span><span class="p">(</span><span class="no">Class</span><span class="p">){</span><span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">classes2</span> <span class="o"><<</span> <span class="n">x</span><span class="p">}</span>
<span class="n">objects_ids</span> <span class="o">=</span> <span class="n">objects</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:object_id</span><span class="p">)</span>
<span class="n">new_objects</span> <span class="o">=</span> <span class="n">objects2</span><span class="p">.</span><span class="nf">reject</span> <span class="p">{</span> <span class="o">|</span><span class="n">e</span><span class="o">|</span> <span class="n">objects_ids</span><span class="p">.</span><span class="nf">include?</span> <span class="n">e</span><span class="p">.</span><span class="nf">object_id</span> <span class="p">}</span>
<span class="nb">puts</span> <span class="s2">"New objects belongs to the classes: </span><span class="si">#{</span> <span class="n">new_objects</span><span class="p">.</span><span class="nf">map</span><span class="p">(</span><span class="o">&</span><span class="ss">:class</span><span class="p">).</span><span class="nf">uniq</span> <span class="si">}</span><span class="s2">"</span>
<span class="nb">puts</span> <span class="s2">"New classes: </span><span class="si">#{</span><span class="n">classes2</span> <span class="o">-</span> <span class="n">classes</span><span class="si">}</span><span class="s2">"</span>
<span class="n">h</span> <span class="o">=</span> <span class="p">{}</span>
<span class="no">ObjectSpace</span><span class="p">.</span><span class="nf">count_objects</span><span class="p">(</span><span class="n">h</span><span class="p">)</span>
<span class="nb">puts</span> <span class="s2">"Counts: </span><span class="si">#{</span> <span class="n">h</span><span class="p">[</span><span class="ss">:T_CLASS</span><span class="p">]</span> <span class="si">}</span><span class="s2">, </span><span class="si">#{</span> <span class="n">h</span><span class="p">[</span><span class="ss">:T_ICLASS</span><span class="p">]</span> <span class="si">}</span><span class="s2">"</span>
</code></pre>
<p>The result is the following:</p>
<pre><code>Counts: 690, 46
New objects belongs to the classes: [Array, Class]
New classes: [Test]
Counts: 692, 46
</code></pre>
<p>This means that the number of <code>T_CLASS</code> is increased by 2 with the creation of 1 class. Why is this the case? Is this a bug?</p>
<p>Consider the slightly modified code with:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="k">class</span> <span class="nc">Test</span>
<span class="k">def</span> <span class="nc">self</span><span class="o">.</span><span class="nf">foo</span>
<span class="k">end</span>
<span class="k">end</span>
</code></pre>
<p>In this case the Singleton class is also created and the results are:</p>
<pre><code>Counts: 690, 46
New objects belongs to the classes: [Array, Class]
New classes: [#<Class:Test>, Test]
Counts: 693, 46
</code></pre>
<p>In this case, <code>T_CLASS</code> is increased by 3. So it seems like the issue is only with normal classes and not singleton ones.</p>
<p>From <a href="https://stackoverflow.com/questions/61031735" class="external">https://stackoverflow.com/questions/61031735</a></p> Ruby master - Bug #15449 (Closed): Range#=== is not using cover in Ruby 2.6https://bugs.ruby-lang.org/issues/154492018-12-21T13:13:00Zana06 (Ana Maria Martinez Gomez)
<pre><code>irb(main):105:0> ('A'..'Z').cover? 'ANA'
=> true
irb(main):106:0> ('A'..'Z') === 'ANA'
=> false
</code></pre>
<p>Is this expected? Should <code>===</code> use cover according to NEWS in Ruby 2.6?</p>
<pre><code>> ruby -v
ruby 2.6.0dev (2018-12-20 trunk 66466) [x86_64-linux]
</code></pre> Ruby master - Bug #15443 (Rejected): Hash#slide with infinite range gives unexpective resulthttps://bugs.ruby-lang.org/issues/154432018-12-20T14:29:06Zana06 (Ana Maria Martinez Gomez)
<p><code>{ 1 => :a, 2 => :b, 3 => :c }.slice(2..)</code> returns <code>{}</code>. I had expected that it retuns <code>{2=>:b, 3=>:c}</code> instead.</p> Ruby master - Bug #15442 (Closed): irb behaves strange in Ruby 2.6https://bugs.ruby-lang.org/issues/154422018-12-20T08:59:47Zana06 (Ana Maria Martinez Gomez)
<p>When trying to press the UP, DOWN, LEFT and RIGHT keys in Ruby 2.6 strange characters are printed instead of moving (or showing the last executed instruction). This works properly for me in Ruby 2.5.</p>
<pre><code>irb(main):004:0> ^[[A^[[A^[[B^[[C^[[D
</code></pre> Ruby master - Bug #15441 (Rejected): undefined method `union' and `difference' in Ruby 2.6https://bugs.ruby-lang.org/issues/154412018-12-20T08:55:20Zana06 (Ana Maria Martinez Gomez)
<p>Using <code>irb</code> with using current Ruby trunk version:</p>
<pre><code>irb(main):008:0> RUBY_VERSION
=> "2.6.0"
irb(main):009:0> [1,3,5,7,9].union([2,3,4,5,6])
Traceback (most recent call last):
2: from /usr/local/bin/irb:11:in `<main>'
1: from (irb):9
NoMethodError (undefined method `union' for [1, 3, 5, 7, 9]:Array)
irb(main):002:0> [1,2,3,4].difference([1,2])
Traceback (most recent call last):
2: from /usr/local/bin/irb:11:in `<main>'
1: from (irb):2
NoMethodError (undefined method `difference' for [1, 2, 3, 4]:Array)
</code></pre> Ruby master - Bug #15436 (Closed): Tests failing in `make check`https://bugs.ruby-lang.org/issues/154362018-12-19T15:30:52Zana06 (Ana Maria Martinez Gomez)
<p>The following tests fail when running <code>check make</code> (after <code>make</code>) in my openSUSE Tumbleweed using current Ruby trunk version:</p>
<pre><code>[ 1080/19451] OpenSSL::TestEC#test_ec_point_mul = 0.00 s
1) Error:
OpenSSL::TestEC#test_ec_point_mul:
OpenSSL::PKey::EC::Point::Error: called a function you should not call
/home/ana/github/ruby/test/openssl/test_pkey_ec.rb:312:in `mul'
/home/ana/github/ruby/test/openssl/test_pkey_ec.rb:312:in `test_ec_point_mul'
[ 6846/19451] TestExtLibs#test_existence_of_fiddle = 0.07 s
2) Failure:
TestExtLibs#test_existence_of_fiddle [/home/ana/github/ruby/test/test_extlibs.rb:20]:
extension library `fiddle' is not found
"pkg-config --exists libffi"
package configuration for libffi is not found
have_header: checking for ffi.h... -------------------- no
</code></pre>
<p>The second seems to be a problem package and not code related - a problem which I don't manage to solve.... :(<br>
But I am not that sure with the first one.</p> Ruby master - Misc #14470 (Closed): Use Commit together with co-authors Github feature in svn com...https://bugs.ruby-lang.org/issues/144702018-02-13T10:27:36Zana06 (Ana Maria Martinez Gomez)
<p>As currently Ruby is using SVN, for "merging" a PR, the PR is closed and the changes added in a SVN commit. In this commit the author is someone from the Ruby core and not the person who wrote the code. The person who wrote the code is mentioned in the commit message, but that doesn't give any visibility to the author of the code. I think giving proper attribution to the contributors of the projects is important to value them.</p>
<p>It seems that any solution was found to solve this problem, but I think that it could be now easily solved with the new <a href="https://github.com/blog/2496-commit-together-with-co-authors" class="external"><em>Commit together with co-authors</em> Github feature</a>.</p>
<p>If in the commit message, instead of</p>
<p><code>Submitted by: @Ana06 <anamma06@gmail.com></code></p>
<p>you write</p>
<p><code>Co-authored-by: Ana María Martínez Gómez <anamma06@gmail.com></code></p>
<p>Github will show the contribution as well.</p>
<p>What do you think? Would you be up to use it? I think it would be a really easy way to give contributors more visibility. 😉</p>
<p>There have been already some discussions in <a href="https://github.com/ruby/ruby/pull/1752" class="external">https://github.com/ruby/ruby/pull/1752</a></p> Ruby master - Feature #14249 (Open): Remove str[match_str]https://bugs.ruby-lang.org/issues/142492017-12-27T13:17:47Zana06 (Ana Maria Martinez Gomez)
<p>I wonder if <code>str[match_str]</code> makes sense.</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="s2">"ana"</span><span class="p">[</span><span class="s1">'a'</span><span class="p">]</span> <span class="o">=></span> <span class="s2">"a"</span>
</code></pre>
<p>I would say this is not expected and it brings problems, for example when accessing nested hashes. For example:</p>
<pre><code class="Ruby syntaxhl" data-language="Ruby"><span class="n">params</span> <span class="o">=</span> <span class="p">{</span> <span class="s2">"user"</span> <span class="o">=></span> <span class="s2">"Nicolas Cage"</span> <span class="p">}</span> <span class="o">=></span> <span class="p">{</span><span class="s2">"user"</span><span class="o">=></span><span class="s2">"Nicolas Cage"</span><span class="p">}</span>
<span class="n">params</span><span class="p">[</span><span class="s2">"user"</span><span class="p">][</span><span class="s2">"age"</span><span class="p">]</span> <span class="o">=></span> <span class="s2">"age"</span>
</code></pre>
<p>I think <code>str[regexp]</code> is enough and that <code>str[match_str]</code> can be removed.</p> Ruby master - Feature #14112 (Rejected): Follow style conventions for Ruby codehttps://bugs.ruby-lang.org/issues/141122017-11-16T10:33:49Zana06 (Ana Maria Martinez Gomez)
<p>The Ruby code in the documentation and in the tests is currently not following any style rules, which leads to long style discussions in PRs as well as making the code more complicate to read and understand.</p>
<p>I would really like that Ruby documentation follows <a href="https://github.com/bbatsov/ruby-style-guide" class="external">Ruby Style Guide</a> or equivalently <a href="https://github.com/bbatsov/rubocop" class="external">Rubocop rules</a> as they are driven by the Ruby community and it would be consistent and helpful when developing that Ruby documentation follows it as well.</p>
<p>This way we wouldn't need to discuss anything about style in PRs. And when copying code from the documentation you don't have to modify it afterwards.</p> Ruby master - Feature #14105 (Feedback): Introduce xor as alias for Set#^https://bugs.ruby-lang.org/issues/141052017-11-14T12:39:44Zana06 (Ana Maria Martinez Gomez)
<p>Not sure if I should also add feautures for the <code>Set</code> class here or if I should do it somewhere else.</p>
<p>I would like to add a more readable method for the exclusive or, currently as <code>^</code> in set. It is in both mathematics, hardware and many other programming languages known as <code>xor</code>, so I think this will help to use it.</p> Ruby master - Feature #14098 (Closed): The HowToContribute guide can be improvedhttps://bugs.ruby-lang.org/issues/140982017-11-10T12:58:42Zana06 (Ana Maria Martinez Gomez)
<p>I miss some important information in the <a href="https://bugs.ruby-lang.org/projects/ruby/wiki/HowToContribute" class="external">HowToContribute guide</a>:</p>
<ul>
<li>how is the code tested? Should I add new test of my code? where, how and how to execute it?</li>
<li>How are important changes tracked? How is the changelog created? should I write my changes somewhere when modifying the code?</li>
<li>Is the code following any style rule?</li>
</ul>
<p>Is this somewhere documented?</p>
<p>Thanks!</p> Ruby master - Feature #14097 (Closed): Add union and difference to Arrayhttps://bugs.ruby-lang.org/issues/140972017-11-10T06:51:04Zana06 (Ana Maria Martinez Gomez)
<p>Currently there is a concat method in ruby which does the same as +, but modifying the object. We could introduce a union and difference methods, which would be the equivalent for the <code>|</code> and <code>-</code> operators. This operators are normally less used due to lack of readability and expressivity. You end seeing thinks like:</p>
<pre><code>array.concat(array2).uniq!
</code></pre>
<p>just because it is more readable. When it could be written like:</p>
<pre><code>array |= array2
</code></pre>
<p>But, as this is not clear for some people, the new method will solve this problem:</p>
<pre><code>array.union(array2)
</code></pre>
<p>And now this is clean and readable, as everybody expect from Ruby, the language focused on simplicity and productivity. ;)</p>
<p>Can I send a PR? :)</p>