A Range represents an interval: a set of values with a beginning and an end.
Ranges may be constructed using the usual .new method or with literals:
x..y # an inclusive range, in mathematics: [x, y] x...y # an exclusive range, in mathematics: [x, y) (x..) # an endless range, in mathematics: >= x ..y # a beginless inclusive range, in mathematics: <= y ...y # a beginless exclusive range, in mathematics: < y
See Range literals in the language reference.
An easy way to remember which one is inclusive and which one is exclusive it to think of the extra dot as if it pushes y further away, thus leaving it outside of the range.
Ranges typically involve integers, but can be created using arbitrary objects as long as they define succ (or pred for #reverse_each), to get the next element in the range, and < and #==, to know when the range reached the end:
# Represents a string of 'x's.
struct Xs
include Comparable(Xs)
getter size
def initialize(@size : Int32)
end
def succ
Xs.new(@size + 1)
end
def <=>(other)
@size <=> other.size
end
def inspect(io)
@size.times { io << 'x' }
end
def to_s(io)
io << @size << ' '
inspect(io)
end
end An example of using Xs to construct a range:
r = Xs.new(3)..Xs.new(6) r.to_s # => "xxx..xxxxxx" r.to_a # => [Xs.new(3), Xs.new(4), Xs.new(5), Xs.new(6)] r.includes?(Xs.new(5)) # => true
Constructs a Range using the given beginning and end.
Same as #includes?, useful for the case expression.
Returns the object that defines the beginning of this range.
By using binary search, returns the first element for which the passed block returns a truthy value.
Same as #includes?.
Returns an Iterator that cycles over the values of this range.
Iterates over the elements of this range, passing each in turn to the block.
Returns an Iterator over the elements of this range.
Returns the object that defines the end of the range.
Returns true if this range excludes the end element.
Returns true if the range is exclusive.
Returns true if this range includes the given value.
Appends this struct's name and instance variables names and values to the given IO.
Returns an Array with the results of running the block against each element of the collection.
Iterates over the elements of this range in reverse order, passing each in turn to the block.
Returns a reverse Iterator over the elements of this range.
Optimized version of Enumerable#sample that runs in O(1) time when self is an Int or Float range.
Returns an Array of n random elements from self.
Returns the number of values in this range.
Optimized version of Enumerable#sum that runs in O(1) time when self is an Int range.
Same as #inspect(io).
Iterable(B)
Enumerable(B)
Enumerable(B)
Struct
Struct
Value
Object
Object
Object
Constructs a Range using the given beginning and end.
Range.new(1, 10) # => 1..10 Range.new(1, 10, exclusive: true) # => 1...10
Same as #includes?, useful for the case expression.
case 79 when 1..50 then puts "low" when 51..75 then puts "medium" when 76..100 then puts "high" end
Produces:
high
See also: Object#===.
Returns the object that defines the beginning of this range.
(1..10).begin # => 1 (1...10).begin # => 1
By using binary search, returns the first element for which the passed block returns a truthy value.
If the block returns a falsey value, the element to be found lies behind. If the block returns a truthy value, the element to be found is itself or lies in front.
Returns nil if the block didn't return a truthy value for any element.
(0..10).bsearch { |x| x >= 5 } # => 5
(0..Float64::INFINITY).bsearch { |x| x ** 4 >= 256 } # => 4 Same as #includes?.
Returns an Iterator that cycles over the values of this range.
(1..3).cycle.first(5).to_a # => [1, 2, 3, 1, 2]
Iterates over the elements of this range, passing each in turn to the block.
(10..15).each { |n| print n, ' ' }
# prints: 10 11 12 13 14 15 Returns an Iterator over the elements of this range.
(1..3).each.skip(1).to_a # => [2, 3]
Returns the object that defines the end of the range.
(1..10).end # => 10 (1...10).end # => 10
Returns true if this range excludes the end element.
(1..10).excludes_end? # => false (1...10).excludes_end? # => true
Returns true if the range is exclusive. Returns false otherwise (default).
Returns true if this range includes the given value.
(1..10).includes?(4) # => true (1..10).includes?(10) # => true (1..10).includes?(11) # => false (1...10).includes?(9) # => true (1...10).includes?(10) # => false
Appends this struct's name and instance variables names and values to the given IO.
struct Point def initialize(@x : Int32, @y : Int32) end end p1 = Point.new 1, 2 p1.to_s # "Point(@x=1, @y=2)" p1.inspect # "Point(@x=1, @y=2)"
Returns an Array with the results of running the block against each element of the collection.
[1, 2, 3].map { |i| i * 10 } # => [10, 20, 30] Iterates over the elements of this range in reverse order, passing each in turn to the block.
(10...15).reverse_each { |n| print n, ' ' }
# prints: 14 13 12 11 10 Returns a reverse Iterator over the elements of this range.
(1..3).reverse_each.skip(1).to_a # => [2, 1]
Optimized version of Enumerable#sample that runs in O(1) time when self is an Int or Float range. In these cases, this range is considered to be a distribution of numeric values rather than a collection of elements, and the method simply calls random.rand(self).
Raises ArgumentError if self is an open range.
Returns an Array of n random elements from self. All elements have equal probability of being drawn. Sampling is done without replacement; if n is larger than the size of this collection, the returned Array has the same size as self.
Raises ArgumentError if n is negative.
[1, 2, 3, 4, 5].sample(2) # => [3, 5]
{1, 2, 3, 4, 5}.sample(2) # => [3, 4] Uses the random instance when provided if the randomness needs to be controlled or to follow some traits. For example the following calls use a custom seed or a secure random source:
{1, 2, 3, 4, 5}.sample(2, Random.new(1)) # => [1, 5]
{1, 2, 3, 4, 5}.sample(2, Random::Secure) # => [2, 5] If self is not empty and n is equal to 1, calls #sample(random) exactly once. Thus, random will be left in a different state compared to the implementation in Enumerable.
Returns the number of values in this range.
If both the beginning and the end of this range are Ints, runs in constant time instead of linear.
(3..8).size # => 6 (3...8).size # => 5
Raises OverflowError if the difference is bigger than Int32. Raises ArgumentError if either #begin or #end are nil.
Iterates from #begin to #end incrementing by the amount of step on each iteration.
ary = [] of Int32 (1..4).step(by: 2) do |x| ary << x end ary # => [1, 3] (1..4).step(by: 2).to_a # => [1, 3] (1..4).step(by: 1).to_a # => [1, 2, 3, 4] (1...4).step(by: 1).to_a # => [1, 2, 3]
If B is a Steppable, implementation is delegated to Steppable#step. Otherwise #succ method is expected to be defined on #begin and its successors and iteration is based on calling #succ sequentially (step times per iteration).
Raises ArgumentError if #begin is nil.
Iterates from #begin to #end incrementing by the amount of step on each iteration.
ary = [] of Int32 (1..4).step(by: 2) do |x| ary << x end ary # => [1, 3] (1..4).step(by: 2).to_a # => [1, 3] (1..4).step(by: 1).to_a # => [1, 2, 3, 4] (1...4).step(by: 1).to_a # => [1, 2, 3]
If B is a Steppable, implementation is delegated to Steppable#step. Otherwise #succ method is expected to be defined on #begin and its successors and iteration is based on calling #succ sequentially (step times per iteration).
Raises ArgumentError if #begin is nil.
Optimized version of Enumerable#sum that runs in O(1) time when self is an Int range.
Same as #inspect(io).
© 2012–2026 Manas Technology Solutions.
Licensed under the Apache License, Version 2.0.
https://crystal-lang.org/api/1.19.0/Range.html