The first and perhaps most natural use of ranges is to express a
sequence.
Sequences have a start point, an end point, and a way to
produce successive values in the sequence. In Ruby, these sequences
are created using the ``..'' and ``...'' range operators. The
two-dot form creates an inclusive range, while the three-dot form
creates a range that excludes the specified high value.

1..10
'a'..'z'
0...anArray.length

In Ruby, unlike in some earlier versions of Perl, ranges are not
represented internally as lists: the sequence 1..100000 is held as a
Range object containing references to two Fixnum objects. If
you need to, you can convert a range to a list using the
to_a method.

(1..10).to_a

�

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

('bar'..'bat').to_a

�

["bar", "bas", "bat"]

Ranges implement methods that let you iterate over them and test their
contents in a variety of ways.

digits = 0..9

digits.include?(5)

�

true

digits.min

�

0

digits.max

�

9

digits.reject {|i| i < 5 }

�

[5, 6, 7, 8, 9]

digits.each do |digit|

dial(digit)

end

So far we've shown ranges of numbers and strings. However, as you'd
expect from an object-oriented language, Ruby can create ranges based
on objects that you define. The only constraints are that the objects
must respond to succ by returning the next object in sequence
and the objects must be comparable using <=>,
the general comparison operator.
Sometimes called the
spaceship operator, <=> compares two values, returning -1, 0, or +1
depending on whether the first is less than, equal to, or greater than
the second.

Here's a simple class that represents rows of ``#'' signs. We might
use it as a text-based stub when testing the jukebox volume control.