Can anyone shed some insight onto why the following happens?
irb(main):001:0> r = '1'..'30'
=> "1".."30"
irb(main):002:0> r.each do |i|
irb(main):003:1* puts "#{i} : #{r.include?(i)}"
irb(main):004:1> end
1 : true
2 : true
3 : true
4 : false
5 : false
6 : false
7 : false
8 : false
9 : false
10 : true
...
(snip.. the String-numbers here evaluate to true)
...
29 : true
30 : true
=> "1".."30"
I'd expect the above to be all true
s. If I do the following:
irb(main):005:0> r.to_a.each do |i|
irb(main):006:1* puts "#{i} : #{r.to_a.include?(i)}"
irb(main):007:1> end
1 : true
2 : true
...
(snip.. the String-numbers here evaluate to true)
...
29 : true
30 : true
=> ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "
15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28
", "29", "30"]
then I get what I expected. Am I missing something with how ranges work or could this be a bug (probably the former)? My bad in advance if this is a noob question. Hard/soft quoting doesn't make a difference, and the same problem happens with ranges of numbers in String-form for values other than between 1 to 30.
This is a quirk of how ranges work in Ruby. The objects are generated by repeatedly calling succ
, but membership is determined by x >= r.start && x <= r.end
. Strings in Ruby do not have special behavior for ordering numbers — '4' is greater than '10' because '4' is greater than '1'. So any single-digit numbers that are higher than the first digit of the end value will appear not to be in range.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With