https://redmine.ruby-lang.org/https://redmine.ruby-lang.org/favicon.ico?17113305112015-10-12T21:06:13ZRuby Issue Tracking SystemRuby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=544332015-10-12T21:06:13Zdpulliam (Dylan Pulliam)dylan.pulliam@gmail.com
<ul></ul><p>Brian Shirai wrote:</p>
<blockquote>
<p>The Numeric#step documentation states:</p>
<p>"If any of the arguments are floating point numbers, all are converted to floats..."</p>
<p><a href="https://github.com/ruby/ruby/blob/trunk/numeric.c#L1921" class="external">https://github.com/ruby/ruby/blob/trunk/numeric.c#L1921</a></p>
<p>Is the following code intended to be described by that documentation?</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="mf">1.1</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="mf">5.1</span><span class="p">,</span> <span class="s2">"1"</span><span class="p">)</span> <span class="p">{}</span>
</code></pre>
<p>Previously (eg 2.0.0) resulted in a TypeError:</p>
<pre><code>$ ruby -v -e 'p 1.1.step(5.1, "1") {}'
ruby 2.0.0p247 (2013-06-27) [x86_64-darwin13.0.1]
-e:1:in `step': no implicit conversion to float from string (TypeError)
from -e:1:in `<main>'
</code></pre>
<p>In 2.1.1, at least, an ArgumentError is raised:</p>
<pre><code>$ ruby -v -e 'p 1.1.step(5.1, "1") {}'
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin13.0]
-e:1:in `>': comparison of String with 0 failed (ArgumentError)
from -e:1:in `step'
from -e:1:in `<main>'
</code></pre>
<p>What's the intended behavior?</p>
</blockquote>
<p>Hey Brian,</p>
<p>TL;DR</p>
<p>Your calling step with an invalid parameter. It is not intended to take a string. Make sure that the params you pass in are an integer or float and you should be good to go. The main point referenced by “if any of the arguments are floating point numbers, all are converted to floats..” is that even if you call the function on an integer, if you pass in floats it will treat everything (by casting/converting) to a floating point number.</p>
<p>For Example:</p>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">010</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="mi">1</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">i</span> <span class="p">}</span>
<span class="mf">1.0</span>
<span class="mf">2.0</span>
<span class="mf">3.0</span>
<span class="o">=></span> <span class="mi">1</span>
</code></pre>
<p>All things considered if I have the time this week I can put together a patch that explains the parameters a bit more (no promises! been busy) in the documentation to clear up the confusion. If you already have the docs written but are not comfortable patching yourself I would be happy to help you with the patch. It is pleasantly simple once you have done it a couple times.</p>
<p>The Good Stuff</p>
<p>I looked into this and here is what I have found:</p>
<a name="1-if-any-of-the-arguments-are-floating-point-numbers-all-are-converted-to-floats"></a>
<h4 >1) “if any of the arguments are floating point numbers, all are converted to floats..”<a href="#1-if-any-of-the-arguments-are-floating-point-numbers-all-are-converted-to-floats" class="wiki-anchor">¶</a></h4>
<p>This does not really apply to the code example you provided because you are submitting a string: i.e. <code>1.1.step(5.1, "1") {}</code> the “1” is what is messing stuff up (more on that below).</p>
<p>A better example of the float conversion would be as follows. There are two main situations where step deals with all floats:</p>
<a name="Case-1-All-params-are-floats"></a>
<h5 >Case 1: All params are floats<a href="#Case-1-All-params-are-floats" class="wiki-anchor">¶</a></h5>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="mf">1.1</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="mf">3.1</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">i</span> <span class="p">}</span>
<span class="mf">1.1</span>
<span class="mf">2.1</span>
<span class="mf">3.1</span>
<span class="o">=></span> <span class="mf">1.1</span>
</code></pre>
<a name="Case-2-One-or-more-params-are-floats"></a>
<h5 >Case 2: One or more params are floats<a href="#Case-2-One-or-more-params-are-floats" class="wiki-anchor">¶</a></h5>
<pre><code class="ruby syntaxhl" data-language="ruby"><span class="n">irb</span><span class="p">(</span><span class="n">main</span><span class="p">):</span><span class="mo">001</span><span class="p">:</span><span class="mi">0</span><span class="o">></span> <span class="mi">1</span><span class="p">.</span><span class="nf">step</span><span class="p">(</span><span class="mi">3</span><span class="p">,</span> <span class="mf">1.0</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">i</span> <span class="p">}</span>
<span class="mf">1.0</span>
<span class="mf">2.0</span>
<span class="mf">3.0</span>
<span class="o">=></span> <span class="mi">1</span>
</code></pre>
<p>Case 2 is what the documentation is referring too. As you can see in the above example, even though the object that we are calling step on is an integer and the first param is an integer, because we have a floating point on the last parameter, all of the integers are converted to float.</p>
<p>** Note here that even though it printed out floats the number returned will be the object you called step on. In this case an Integer. So the float conversion does not change the object you call step on.</p>
<h4>2) <a href="https://github.com/ruby/ruby/blob/trunk/numeric.c#L1921" class="external">https://github.com/ruby/ruby/blob/trunk/numeric.c#L1921</a>
</h4>
<p>This refers to the .ceil function which follows a known practice in computer science for mapping a real number to the largest following integer.</p>
<a name="3-Is-the-following-code-intended-to-be-described-by-that-documentation"></a>
<h4 >3) Is the following code intended to be described by that documentation?<a href="#3-Is-the-following-code-intended-to-be-described-by-that-documentation" class="wiki-anchor">¶</a></h4>
<p>Because .ceil is returning an integer it is unlikely to apply to the case where #step converts to float since we are actually converting from integer to float and not the other way around. ( please double check this, i did not dive super deep into the C code but concluded this from the comment referenced by the link)</p>
<a name="4-Whats-the-intended-behavior"></a>
<h4 >4) What’s the intended behavior?<a href="#4-Whats-the-intended-behavior" class="wiki-anchor">¶</a></h4>
<p>Ultimately I think you actually have the intended behavior down. Basically step from the number you are calling the function on, up to the number in the first param, using the step counter provided in the second param. Just make sure to pass an integer or floating point and not a string.</p>
<p>The confusion comes from the two errors you got.</p>
<p>The first error, like you said, came from ruby version 2.0 and causes a type error because there was no implicit way to convert the string to a float.</p>
<p>i.e. <code>1.0 + "1"</code></p>
<p>The second error from ruby version 2.1 is given for a similar reason but is a better description for the given context. It’s basically saying “hey thanks for calling this function but you’re doing it wrong :P” Ultimately it does not like the string you passed in.</p>
<p>I hope this helps and if I was wrong about or misinterpreted any points above I would love to hear more.</p>
<p>Good Luck!</p> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=569372016-02-09T17:30:06Zdpulliam (Dylan Pulliam)dylan.pulliam@gmail.com
<ul><li><strong>File</strong> <a href="/attachments/5784">0001-Update-documentation-on-Numeric-step.patch</a> <a class="icon-only icon-download" title="Download" href="/attachments/download/5784/0001-Update-documentation-on-Numeric-step.patch">0001-Update-documentation-on-Numeric-step.patch</a> added</li></ul><p>i finally got around to writing the patch : ) pretty basic but let me know what you think!</p> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=570112016-02-16T09:29:47Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Status</strong> changed from <i>Open</i> to <i>Assigned</i></li><li><strong>Assignee</strong> set to <i>nobu (Nobuyoshi Nakada)</i></li></ul> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=571462016-02-26T01:01:25Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Description</strong> updated (<a title="View differences" href="/journals/57146/diff?detail_id=40341">diff</a>)</li></ul><p><a href="https://docs.google.com/document/d/1rj7ODOCSfcsQeBd6-p-NiVwqxDUg05G66LwDOkKOGTw/pub" class="external">Developers' meeting log</a></p>
<blockquote>
<p>This issue is because of invalid type, not mismatch the number of arguments.<br>
Comparison <code>String</code> with <code>Numeric</code> should raise <code>TypeError</code></p>
<p>matz: I once thought type mismatch also infringe the contract of arguments, therefore it can be <code>ArgumentError</code> but now they should be separated.</p>
<p>matz: It should raise <code>TypeError</code>.</p>
</blockquote> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=571552016-02-26T05:40:54Znobu (Nobuyoshi Nakada)nobu@ruby-lang.org
<ul><li><strong>Status</strong> changed from <i>Assigned</i> to <i>Closed</i></li></ul><p>Applied in changeset r53949.</p>
<hr>
<p>numeric.c: wrong type step should raise TypeError</p>
<ul>
<li>numeric.c (num_step_scan_args): comparison String with Numeric<br>
should raise TypeError. it is an invalid type, but not a<br>
mismatch the number of arguments. <a href="/issues/9810">[ruby-core:62430]</a> [Bug <a class="issue tracker-1 status-5 priority-4 priority-default closed" title="Bug: Numeric#step behavior with mixed Float, String arguments inconsistent with documentation (Closed)" href="https://redmine.ruby-lang.org/issues/9810">#9810</a>]</li>
</ul> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=576262016-03-24T06:59:04Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul><li><strong>Backport</strong> changed from <i>2.0.0: UNKNOWN, 2.1: UNKNOWN</i> to <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED</i></li></ul> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=576872016-03-25T09:29:36Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul><li><strong>Backport</strong> changed from <i>2.1: REQUIRED, 2.2: REQUIRED, 2.3: REQUIRED</i> to <i>2.1: DONE, 2.2: REQUIRED, 2.3: REQUIRED</i></li></ul><p>ruby_2_1 r54276 merged revision(s) 53949.</p> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=577002016-03-25T14:00:10Zusa (Usaku NAKAMURA)usa@garbagecollect.jp
<ul><li><strong>Backport</strong> changed from <i>2.1: DONE, 2.2: REQUIRED, 2.3: REQUIRED</i> to <i>2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED</i></li></ul><p>The change for ruby_2_1 has been reverted.<br>
I think this is a kind of bug, but incompatible change from another point of view.</p> Ruby master - Bug #9810: Numeric#step behavior with mixed Float, String arguments inconsistent with documentationhttps://redmine.ruby-lang.org/issues/9810?journal_id=581232016-04-18T07:32:49Znaruse (Yui NARUSE)naruse@airemix.jp
<ul><li><strong>Backport</strong> changed from <i>2.1: WONTFIX, 2.2: REQUIRED, 2.3: REQUIRED</i> to <i>2.1: WONTFIX, 2.2: WONTFIX, 2.3: WONTFIX</i></li></ul>