[ruby-core:111272] [Ruby master Bug#19231] Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block

Issue #19231 has been reported by andrykonchin (Andrew Konchin). ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(100.0, 10).take(1).map(&:class) # => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by mrkn (Kenta Murata). `0.step(Float::INFINITY, 10).each` generates Float values until Ruby 2.0 and after Ruby 2.6, but it generates Integer values between Ruby 2.1 and 2.5. The reason why the behavior changes after Ruby 2.6 is due to ArithmeticSequence. `0.step(Float::INFINITY, 10) { ... }` generates Float values until Ruby 2.0, but it generates Integer values after Ruby 2.1. Hence it's also possible that the right behavior is to generate Integer values rather than Float. We need to know the reason for the behavior change in Ruby 2.1. ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-100624 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by Eregon (Benoit Daloze). IMHO Integer makes sense so one can step by N from 0 to infinity with `0.step(Float::INFINITY, 10)` (with `Numeric#step`), since there is no `Integer::INFINITY`. Using Float also can cause significant errors with a big enough step or values. So the rule would be "use floats if `receiver` or `step` is Float (ignore `to/limit`'s type), otherwise leave them as-is. The keyword form already uses integers for "step infinitely": ```ruby
0.step(by: 10).take 2 => [0, 10] 0.step(by: 10) { break _1 } => 0
Probably we need to be consistent with `Range#step` too:
```ruby
> (0..).step(10) { break _1 }
=> 0
> (0..).step(10).take 2
=> [0, 10]
> (0..Float::INFINITY).step(10) { break _1 }
=> 0.0
> (0..Float::INFINITY).step(10).take 2
=> [0.0, 10.0]
---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-100625 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by kyanagi (Kouhei Yanagita). ``` % docker run -it --rm rubylang/all-ruby env ALL_RUBY_SINCE=ruby-1.3 ./all-ruby -e 'inf = 1.0/0.0; 0.step(inf, 10) { |x| p x; break }' ruby-1.3 /tmp/rbFgfjB4:1:in `/': divided by 0 (ZeroDivisionError) from /tmp/rbFgfjB4:1 exit 1 ruby-1.3.1-990215 0 ... ruby-1.6.8 0 ruby-1.8.0 0.0 ... ruby-2.0.0-p648 0.0 ruby-2.1.0-preview1 0 ... ruby-3.3.0-preview2 0 ``` The behavior seems to have changed in version 1.8.0 due to https://github.com/ruby/ruby/commit/936ad40. The behavior seems to have changed in version 2.1.0 due to https://github.com/ruby/ruby/commit/fd4b5b8. The issue is https://bugs.ruby-lang.org/issues/8838. I think the behavior change in Ruby 1.8.0 was likely not intentional but rather accidental. I couldn't find any documentation indicating that the behavior change in Ruby 2.1.0 was intentional. There is no mention in NEWS-2.1.0 either. ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-104953 * Author: andrykonchin (Andrew Konchin) * Status: Open * Priority: Normal * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by nobu (Nobuyoshi Nakada). Weird a little. ```ruby seq = 0.step(Float::INFINITY, 10) p seq.class #=> Enumerator::ArithmeticSequence p seq.first #=> 0 p seq.first(1) #=> [0.0] ``` ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-107216 * Author: andrykonchin (Andrew Konchin) * Status: Open * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by nobu (Nobuyoshi Nakada). https://github.com/nobu/ruby/tree/arith_seq-infinite-end ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-107219 * Author: andrykonchin (Andrew Konchin) * Status: Open * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/

Issue #19231 has been updated by matz (Yukihiro Matsumoto). When `start` and `step` are integers, there's no error, so that it seems OK to make the value passing to the block integers. If any implementation issue or compatibility problem happens, let us discuss later. Matz. ---------------------------------------- Bug #19231: Integer#step and Float::INFINITY - inconsistent behaviour when called with and without a block https://bugs.ruby-lang.org/issues/19231#change-109308 * Author: andrykonchin (Andrew Konchin) * Status: Open * ruby -v: 3.1.2 * Backport: 2.7: UNKNOWN, 3.0: UNKNOWN, 3.1: UNKNOWN ---------------------------------------- The initial issue was reported here https://github.com/oracle/truffleruby/issues/2797. `0.step(Float::INFINITY, 10)` returns: - `Integers` when called with a block - `Floats` when called without a block I would expect `Floats` to be returned in both cases. Examples: ```ruby 0.step(Float::INFINITY, 10).take(1).map(&:class) => [Float] ``` ```ruby 0.step(Float::INFINITY, 10) { |offset| p offset.class; break } # Integer ``` When `to` argument is a finite `Float` value then calling with a block returns `Floats` as well: ```ruby 0.step(100.0, 10) { |offset| p offset.class; break } # Float ``` Wondering whether it's intentional behaviour. I've found a related issue https://bugs.ruby-lang.org/issues/15518. -- https://bugs.ruby-lang.org/
participants (6)
-
andrykonchin (Andrew Konchin)
-
Eregon (Benoit Daloze)
-
kyanagi (Kouhei Yanagita)
-
matz (Yukihiro Matsumoto)
-
mrkn (Kenta Murata)
-
nobu (Nobuyoshi Nakada)