Ruby Range Unexpected Behavior

range, ruby

Solution

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.

Problem

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.

Original source