A `Range` represents an interval—a
set of values with a start and an end. Ranges
may be constructed using the *s*`..`*e* and
*s*`...`*e* literals, or with `Range::new`.
Ranges constructed using `..` run from the start to the end inclusively. Those created using
`...` exclude the end value. When used
as an iterator, ranges return each value in
the sequence.

(-1..-5).to_a #=> [] (-5..-1).to_a #=> [-5, -4, -3, -2, -1] ('a'..'e').to_a #=> ["a", "b", "c", "d", "e"] ('a'...'e').to_a #=> ["a", "b", "c", "d"]

Ranges can be constructed using objects of any type, as long as the objects
can be compared using their `<=>` operator and they support
the `succ` method to return the next object in sequence.

class Xs # represent a string of 'x's include Comparable attr :length def initialize(n) @length = n end def succ Xs.new(@length + 1) end def <=>(other) @length <=> other.length end def to_s sprintf "%2d #{inspect}", @length end def inspect 'x' * @length end end r = Xs.new(3)..Xs.new(6) #=> xxx..xxxxxx r.to_a #=> [xxx, xxxx, xxxxx, xxxxxx] r.member?(Xs.new(5)) #=> true

In the previous code example, class `Xs` includes the `Comparable` module. This is because `Enumerable#member?` checks for
equality using `==`. Including `Comparable` ensures that the `==`
method is defined in terms of the `<=>` method implemented in
`Xs`.