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.