Class

A Range represents an interval—a set of values with a beginning 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 beginning 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"]

Beginless/Endless Ranges

A “beginless range” and “endless range” represents a semi-infinite range. Literal notation for a beginless range is:

(..1)
# or
(...1)

Literal notation for an endless range is:

(1..)
# or similarly
(1...)

Which is equivalent to

(1..nil)  # or similarly (1...nil)
Range.new(1, nil) # or Range.new(1, nil, true)

Beginless/endless ranges are useful, for example, for idiomatic slicing of arrays:

[1, 2, 3, 4, 5][...2]   # => [1, 2]
[1, 2, 3, 4, 5][2...]   # => [3, 4, 5]

Some implementation details:

  • begin of beginless range and end of endless range are nil;

  • each of beginless range raises an exception;

  • each of endless range enumerates infinite sequence (may be useful in combination with Enumerable#take_while or similar methods);

  • (1..) and (1...) are not equal, although technically representing the same sequence.

Custom Objects in Ranges

Ranges can be constructed using any objects that can be compared using the <=> operator. Methods that treat the range as a sequence (each and methods inherited from Enumerable) expect the begin object to implement a succ method to return the next object in sequence. The step and include? methods require the begin object to implement succ or to be numeric.

In the Xs class below both <=> and succ are implemented so Xs can be used to construct ranges. Note that the Comparable module is included so the == method is defined in terms of <=>.

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

An example of using Xs to construct a range:

r = Xs.new(3)..Xs.new(6)   #=> xxx..xxxxxx
r.to_a                     #=> [xxx, xxxx, xxxxx, xxxxxx]
r.member?(Xs.new(5))       #=> true

Class Methods


Deserializes JSON string by constructing new Range object with arguments a serialized by to_json.

Returns a new range based on the given objects begin and end. Optional argument exclude_end determines whether object end is included as the last object in the range:

Range.new(2, 5).to_a            # => [2, 3, 4, 5]
Range.new(2, 5, true).to_a      # => [2, 3, 4]
Range.new('a', 'd').to_a        # => ["a", "b", "c", "d"]
Range.new('a', 'd', true).to_a  # => ["a", "b", "c"]

Instance Methods


No documentation available

Returns true if and only if:

  • other is a range.

  • other.begin == self.begin.

  • other.end == self.end.

  • other.exclude_end? == self.include_end?.

Otherwise returns false.

r = (1..5)
r == (1..5)                # => true
r = Range.new(1, 5)
r == 'foo'                 # => false
r == (2..5)                # => false
r == (1..4)                # => false
r == (1...5)               # => false
r == Range.new(1, 5, true) # => false

Note that even with the same argument, the return values of #== and eql? can differ:

(1..2) == (1..2.0)   # => true
(1..2).eql? (1..2.0) # => false

Related: Range#eql?.

Returns true if object is between self.begin and self.end. false otherwise:

(1..4) === 2       # => true
(1..4) === 5       # => false
(1..4) === 'a'     # => false
(1..4) === 4       # => true
(1...4) === 4      # => false
('a'..'d') === 'c' # => true
('a'..'d') === 'e' # => false

A case statement uses method ===, and so:

case 79
when (1..50)
  "low"
when (51..75)
  "medium"
when (76..100)
  "high"
end # => "high"

case "2.6.5"
when ..."2.4"
  "EOL"
when "2.4"..."2.5"
  "maintenance"
when "2.5"..."3.0"
  "stable"
when "3.1"..
  "upcoming"
end # => "stable"

Returns a hash, that will be turned into a JSON object and represent this object.

Returns the object that defines the beginning of self.

(1..4).begin # => 1
(..2).begin  # => nil

Related: Range#first, Range#end.

Returns an element from self selected by a binary search.

See Binary Searching.

Returns the count of elements, based on an argument or block criterion, if given.

With no argument and no block given, returns the number of elements:

(1..4).count      # => 4
(1...4).count     # => 3
('a'..'d').count  # => 4
('a'...'d').count # => 3
(1..).count       # => Infinity
(..4).count       # => Infinity

With argument object, returns the number of object found in self, which will usually be zero or one:

(1..4).count(2)   # => 1
(1..4).count(5)   # => 0
(1..4).count('a')  # => 0

With a block given, calls the block with each element; returns the number of elements for which the block returns a truthy value:

(1..4).count {|element| element < 3 } # => 2

Related: Range#size.

Returns true if the given argument is within self, false otherwise.

With non-range argument object, evaluates with <= and <.

For range self with included end value (#exclude_end? == false), evaluates thus:

self.begin <= object <= self.end

Examples:

r = (1..4)
r.cover?(1)     # => true
r.cover?(4)     # => true
r.cover?(0)     # => false
r.cover?(5)     # => false
r.cover?('foo') # => false

r = ('a'..'d')
r.cover?('a')     # => true
r.cover?('d')     # => true
r.cover?(' ')     # => false
r.cover?('e')     # => false
r.cover?(0)       # => false

For range r with excluded end value (#exclude_end? == true), evaluates thus:

r.begin <= object < r.end

Examples:

r = (1...4)
r.cover?(1)     # => true
r.cover?(3)     # => true
r.cover?(0)     # => false
r.cover?(4)     # => false
r.cover?('foo') # => false

r = ('a'...'d')
r.cover?('a')     # => true
r.cover?('c')     # => true
r.cover?(' ')     # => false
r.cover?('d')     # => false
r.cover?(0)       # => false

With range argument range, compares the first and last elements of self and range:

r = (1..4)
r.cover?(1..4)     # => true
r.cover?(0..4)     # => false
r.cover?(1..5)     # => false
r.cover?('a'..'d') # => false

r = (1...4)
r.cover?(1..3)     # => true
r.cover?(1..4)     # => false

If begin and end are numeric, cover? behaves like include?

(1..3).cover?(1.5) # => true
(1..3).include?(1.5) # => true

But when not numeric, the two methods may differ:

('a'..'d').cover?('cc')   # => true
('a'..'d').include?('cc') # => false

Returns false if either:

  • The begin value of self is larger than its end value.

  • An internal call to <=> returns nil; that is, the operands are not comparable.

Related: Range#include?.

With a block given, passes each element of self to the block:

a = []
(1..4).each {|element| a.push(element) } # => 1..4
a # => [1, 2, 3, 4]

Raises an exception unless self.first.respond_to?(:succ).

With no block given, returns an enumerator.

Returns the object that defines the end of self.

(1..4).end  # => 4
(1...4).end # => 4
(1..).end   # => nil

Related: Range#begin, Range#last.

An alias for to_a

Returns true if and only if:

  • other is a range.

  • other.begin eql? self.begin.

  • other.end eql? self.end.

  • other.exclude_end? == self.include_end?.

Otherwise returns false.

r = (1..5)
r.eql?(1..5)                  # => true
r = Range.new(1, 5)
r.eql?('foo')                 # => false
r.eql?(2..5)                  # => false
r.eql?(1..4)                  # => false
r.eql?(1...5)                 # => false
r.eql?(Range.new(1, 5, true)) # => false

Note that even with the same argument, the return values of #== and eql? can differ:

(1..2) == (1..2.0)   # => true
(1..2).eql? (1..2.0) # => false

Related: Range#==.

Returns true if self excludes its end value; false otherwise:

Range.new(2, 5).exclude_end?       # => false
Range.new(2, 5, true).exclude_end? # => true
(2..5).exclude_end?                # => false
(2...5).exclude_end?               # => true

With no argument, returns the first element of self, if it exists:

(1..4).first     # => 1
('a'..'d').first # => "a"

With non-negative integer argument n given, returns the first n elements in an array:

(1..10).first(3) # => [1, 2, 3]
(1..10).first(0) # => []
(1..4).first(50) # => [1, 2, 3, 4]

Raises an exception if there is no first element:

(..4).first # Raises RangeError

Returns the integer hash value for self. Two range objects r0 and r1 have the same hash value if and only if r0.eql?(r1).

Related: Range#eql?, Object#hash.

Returns a string representation of self, including begin.inspect and end.inspect:

(1..4).inspect  # => "1..4"
(1...4).inspect # => "1...4"
(1..).inspect   # => "1.."
(..4).inspect   # => "..4"

Note that returns from to_s and inspect may differ:

('a'..'d').to_s    # => "a..d"
('a'..'d').inspect # => "\"a\"..\"d\""

Related: Range#to_s.

With no argument, returns the last element of self, if it exists:

(1..4).last     # => 4
('a'..'d').last # => "d"

Note that last with no argument returns the end element of self even if exclude_end? is true:

(1...4).last     # => 4
('a'...'d').last # => "d"

With non-negative integer argument n given, returns the last n elements in an array:

(1..10).last(3) # => [8, 9, 10]
(1..10).last(0) # => []
(1..4).last(50) # => [1, 2, 3, 4]

Note that last with argument does not return the end element of self if exclude_end? it true:

(1...4).last(3)     # => [1, 2, 3]
('a'...'d').last(3) # => ["a", "b", "c"]

Raises an exception if there is no last element:

(1..).last # Raises RangeError

Returns the maximum value in self, using method <=> or a given block for comparison.

With no argument and no block given, returns the maximum-valued element of self.

(1..4).max     # => 4
('a'..'d').max # => "d"
(-4..-1).max   # => -1

With non-negative integer argument n given, and no block given, returns the n maximum-valued elements of self in an array:

(1..4).max(2)     # => [4, 3]
('a'..'d').max(2) # => ["d", "c"]
(-4..-1).max(2)   # => [-1, -2]
(1..4).max(50)    # => [4, 3, 2, 1]

If a block is given, it is called:

  • First, with the first two element of self.

  • Then, sequentially, with the so-far maximum value and the next element of self.

To illustrate:

(1..4).max {|a, b| p [a, b]; a <=> b } # => 4

Output:

[2, 1]
[3, 2]
[4, 3]

With no argument and a block given, returns the return value of the last call to the block:

(1..4).max {|a, b| -(a <=> b) } # => 1

With non-negative integer argument n given, and a block given, returns the return values of the last n calls to the block in an array:

(1..4).max(2) {|a, b| -(a <=> b) }  # => [1, 2]
(1..4).max(50) {|a, b| -(a <=> b) } # => [1, 2, 3, 4]

Returns an empty array if n is zero:

(1..4).max(0)                      # => []
(1..4).max(0) {|a, b| -(a <=> b) } # => []

Returns nil or an empty array if:

  • The begin value of the range is larger than the end value:

    (4..1).max                         # => nil
    (4..1).max(2)                      # => []
    (4..1).max {|a, b| -(a <=> b) }    # => nil
    (4..1).max(2) {|a, b| -(a <=> b) } # => []
    
  • The begin value of an exclusive range is equal to the end value:

    (1...1).max                          # => nil
    (1...1).max(2)                       # => []
    (1...1).max  {|a, b| -(a <=> b) }    # => nil
    (1...1).max(2)  {|a, b| -(a <=> b) } # => []
    

Raises an exception if either:

  • self is a endless range: (1..).

  • A block is given and self is a beginless range.

Related: Range#min, Range#minmax.

Returns true if object is an element of self, false otherwise:

(1..4).include?(2)        # => true
(1..4).include?(5)        # => false
(1..4).include?(4)        # => true
(1...4).include?(4)       # => false
('a'..'d').include?('b')  # => true
('a'..'d').include?('e')  # => false
('a'..'d').include?('B')  # => false
('a'..'d').include?('d')  # => true
('a'...'d').include?('d') # => false

If begin and end are numeric, include? behaves like cover?

(1..3).include?(1.5) # => true
(1..3).cover?(1.5) # => true

But when not numeric, the two methods may differ:

('a'..'d').include?('cc') # => false
('a'..'d').cover?('cc')   # => true

Related: Range#cover?.

Range#member? is an alias for Range#include?.

Returns the minimum value in self, using method <=> or a given block for comparison.

With no argument and no block given, returns the minimum-valued element of self.

(1..4).min     # => 1
('a'..'d').min # => "a"
(-4..-1).min   # => -4

With non-negative integer argument n given, and no block given, returns the n minimum-valued elements of self in an array:

(1..4).min(2)     # => [1, 2]
('a'..'d').min(2) # => ["a", "b"]
(-4..-1).min(2)   # => [-4, -3]
(1..4).min(50)    # => [1, 2, 3, 4]

If a block is given, it is called:

  • First, with the first two element of self.

  • Then, sequentially, with the so-far minimum value and the next element of self.

To illustrate:

(1..4).min {|a, b| p [a, b]; a <=> b } # => 1

Output:

[2, 1]
[3, 1]
[4, 1]

With no argument and a block given, returns the return value of the last call to the block:

(1..4).min {|a, b| -(a <=> b) } # => 4

With non-negative integer argument n given, and a block given, returns the return values of the last n calls to the block in an array:

(1..4).min(2) {|a, b| -(a <=> b) }  # => [4, 3]
(1..4).min(50) {|a, b| -(a <=> b) } # => [4, 3, 2, 1]

Returns an empty array if n is zero:

(1..4).min(0)                      # => []
(1..4).min(0) {|a, b| -(a <=> b) } # => []

Returns nil or an empty array if:

  • The begin value of the range is larger than the end value:

    (4..1).min                         # => nil
    (4..1).min(2)                      # => []
    (4..1).min {|a, b| -(a <=> b) }    # => nil
    (4..1).min(2) {|a, b| -(a <=> b) } # => []
    
  • The begin value of an exclusive range is equal to the end value:

    (1...1).min                          # => nil
    (1...1).min(2)                       # => []
    (1...1).min  {|a, b| -(a <=> b) }    # => nil
    (1...1).min(2)  {|a, b| -(a <=> b) } # => []
    

Raises an exception if either:

  • self is a beginless range: (..4).

  • A block is given and self is an endless range.

Related: Range#max, Range#minmax.

Returns a 2-element array containing the minimum and maximum value in self, either according to comparison method <=> or a given block.

With no block given, returns the minimum and maximum values, using <=> for comparison:

(1..4).minmax     # => [1, 4]
(1...4).minmax    # => [1, 3]
('a'..'d').minmax # => ["a", "d"]
(-4..-1).minmax   # => [-4, -1]

With a block given, the block must return an integer:

  • Negative if a is smaller than b.

  • Zero if a and b are equal.

  • Positive if a is larger than b.

The block is called self.size times to compare elements; returns a 2-element Array containing the minimum and maximum values from self, per the block:

(1..4).minmax {|a, b| -(a <=> b) } # => [4, 1]

Returns [nil, nil] if:

  • The begin value of the range is larger than the end value:

    (4..1).minmax                      # => [nil, nil]
    (4..1).minmax {|a, b| -(a <=> b) } # => [nil, nil]
    
  • The begin value of an exclusive range is equal to the end value:

    (1...1).minmax                          # => [nil, nil]
    (1...1).minmax  {|a, b| -(a <=> b) }    # => [nil, nil]
    

Raises an exception if self is a beginless or an endless range.

Related: Range#min, Range#max.

Returns the count of elements in self if both begin and end values are numeric; otherwise, returns nil:

(1..4).size      # => 4
(1...4).size     # => 3
(1..).size       # => Infinity
('a'..'z').size  #=> nil

Related: Range#count.

Iterates over the elements of self.

With a block given and no argument, calls the block each element of the range; returns self:

a = []
(1..5).step {|element| a.push(element) } # => 1..5
a # => [1, 2, 3, 4, 5]
a = []
('a'..'e').step {|element| a.push(element) } # => "a".."e"
a # => ["a", "b", "c", "d", "e"]

With a block given and a positive integer argument n given, calls the block with element 0, element n, element 2n, and so on:

a = []
(1..5).step(2) {|element| a.push(element) } # => 1..5
a # => [1, 3, 5]
a = []
('a'..'e').step(2) {|element| a.push(element) } # => "a".."e"
a # => ["a", "c", "e"]

With no block given, returns an enumerator, which will be of class Enumerator::ArithmeticSequence if self is numeric; otherwise of class Enumerator:

e = (1..5).step(2) # => ((1..5).step(2))
e.class            # => Enumerator::ArithmeticSequence
('a'..'e').step # => #<Enumerator: ...>

Returns an array containing the elements in self, if a finite collection; raises an exception otherwise.

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

Range#entries is an alias for Range#to_a.

Stores class name (Range) with JSON array of arguments a which include first (integer), last (integer), and exclude_end? (boolean) as JSON string.

Returns a string representation of self, including begin.to_s and end.to_s:

(1..4).to_s  # => "1..4"
(1...4).to_s # => "1...4"
(1..).to_s   # => "1.."
(..4).to_s   # => "..4"

Note that returns from to_s and inspect may differ:

('a'..'d').to_s    # => "a..d"
('a'..'d').inspect # => "\"a\"..\"d\""

Related: Range#inspect.