Here are two range values.
('1'..'10').to_a => ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]
but,
('2'..'10').to_a => []
Why does the second one return an empty array in ruby 1.8.7?
The issue is that Ruby 1.8 is trying to determine whether ('2'..'10') is a valid range as part of its analysis of the code, and deciding that it's invalid. '2' sorts after '10' making the range values backwards.
This is a common problem when people try to sort string values, and they'll encounter it again and again until they learn that trick never works.
Using 1.8.7:
('2'..'10').to_a
=> []
('02'..'10').to_a
=> ["02", "03", "04", "05", "06", "07", "08", "09", "10"]
Or:
(2..10).map(&:to_s)
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10"]
I'd probably use the last method if I needed compatibility with 1.8 and 1.9+ Rubies.
irb(main):001:0> '2' > '10'
=> true
irb(main):002:0> '1'>'10'
=> false
Because of the string comparison algorithm, range cannot be created with lower bound bigger than the upper bound.
ACTUALLY it works in 1.9.3. Strange.
(1..5), 1 is the lower bound and 5 is an upper bound. Range class uses succ method on lower bound until it reaches the upper bound. succ method in string returns '10' after '9' in 1.9.3, which does not seem logical to me personally.succ returns next element in an implied sequence. You don't expect that 5.succ == 4, do you? That is why (5..1).to_a == []. Hope you get the idea.That's not what I'm getting:
irb(main):001:0> ('2'..'10').to_a
=> ["2", "3", "4", "5", "6", "7", "8", "9", "10"]
Unrelated to the question, though: the correct way is:
(2..10).to_a
(I am using Ruby 1.9.3)
('2'.to_i..'10'.to_i).to_a