class Range
A Range object represents a collection of values that are between given begin and end values.
You can create an Range object explicitly with:
-
A range literal:
# Ranges that use '..' to include the given end value. (1..4).to_a # => [1, 2, 3, 4] ('a'..'d').to_a # => ["a", "b", "c", "d"] # Ranges that use '...' to exclude the given end value. (1...4).to_a # => [1, 2, 3] ('a'...'d').to_a # => ["a", "b", "c"]
-
Ranges that by default include the given end value.
Range.new(1, 4).to_a# => [1, 2, 3, 4] Range.new('a', 'd').to_a # => ["a", "b", "c", "d"] #Ranges that use third argument
exclude_endto exclude the given end value.Range.new(1, 4, true).to_a # => [1, 2, 3]Range.new('a', 'd', true).to_a # => ["a", "b", "c"]
Beginless Ranges
A beginless range has a definite end value, but a nil begin value. Such a range includes all values up to the end value.
r = (..4) # => nil..4 r.begin # => nil r.include?(-50) # => true r.include?(4) # => true r = (...4) # => nil...4 r.include?(4) # => false Range.new(nil, 4) # => nil..4 Range.new(nil, 4, true) # => nil...4
A beginless range may be used to slice an array:
a = [1, 2, 3, 4] # Include the third array element in the slice r = (..2) # => nil..2 a[r] # => [1, 2, 3] # Exclude the third array element from the slice r = (...2) # => nil...2 a[r] # => [1, 2]
Method each for a beginless range raises an exception.
Endless Ranges
An endless range has a definite begin value, but a nil end value. Such a range includes all values from the begin value.
r = (1..) # => 1.. r.end # => nil r.include?(50) # => true Range.new(1, nil) # => 1..
The literal for an endless range may be written with either two dots or three. The range has the same elements, either way. But note that the two are not equal:
r0 = (1..) # => 1.. r1 = (1...) # => 1... r0.begin == r1.begin # => true r0.end == r1.end # => true r0 == r1 # => false
An endless range may be used to slice an array:
a = [1, 2, 3, 4] r = (2..) # => 2.. a[r] # => [3, 4]
Method each for an endless range calls the given block indefinitely:
a = [] r = (1..) r.each do |i| a.push(i) if i.even? break if i > 10 end a # => [2, 4, 6, 8, 10]
A range can be both beginless and endless. For literal beginless, endless ranges, at least the beginning or end of the range must be given as an explicit nil value. It is recommended to use an explicit nil beginning and end, since that is what Ruby uses for Range#inspect:
(nil..) # => (nil..nil) (..nil) # => (nil..nil) (nil..nil) # => (nil..nil)
Ranges and Other Classes
An object may be put into a range if its class implements instance method <=>. Ruby core classes that do so include Array, Complex, File::Stat, Float, Integer, Kernel, Module, Numeric, Rational, String, Symbol, and Time.
Example:
t0 = Time.now # => 2021-09-19 09:22:48.4854986 -0500 t1 = Time.now # => 2021-09-19 09:22:56.0365079 -0500 t2 = Time.now # => 2021-09-19 09:23:08.5263283 -0500 (t0..t2).include?(t1) # => true (t0..t1).include?(t2) # => false
A range can be iterated over only if its elements implement instance method succ. Ruby core classes that do so include Integer, String, and Symbol (but not the other classes mentioned above).
Iterator methods include:
-
Included from module Enumerable:
each_entry,each_with_index,
Example:
a = [] (1..4).each {|i| a.push(i) } a # => [1, 2, 3, 4]
Ranges and User-Defined Classes
A user-defined class that is to be used in a range must implement instance method <=>; see Integer#<=>. To make iteration available, it must also implement instance method succ; see Integer#succ.
The class below implements both <=> and succ, and so can be used both to construct ranges and to iterate over them. Note that the Comparable module is included so the == method is defined in terms of <=>.
# Represent a string of 'X' characters. class Xs include Comparable attr_accessor :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.include?(Xs.new(5)) #=> true r.include?(Xs.new(7)) #=> false
What’s Here
First, what’s elsewhere. Class Range:
-
Inherits from class Object.
-
Includes module Enumerable, which provides dozens of additional methods.
Here, class Range provides methods that are useful for:
Methods for Creating a Range
-
::new: Returns a new range.
Methods for Querying
-
begin: Returns the begin value given forself. -
bsearch: Returns an element fromselfselected by a binary search. -
count: Returns a count of elements inself. -
end: Returns the end value given forself. -
exclude_end?: Returns whether the end object is excluded. -
first: Returns the first elements ofself. -
hash: Returns the integer hash code. -
last: Returns the last elements ofself. -
max: Returns the maximum values inself. -
min: Returns the minimum values inself. -
minmax: Returns the minimum and maximum values inself. -
size: Returns the count of elements inself.
Methods for Comparing
-
==: Returns whether a given object is equal toself(uses==). -
===: Returns whether the given object is between the begin and end values. -
cover?: Returns whether a given object is withinself. -
eql?: Returns whether a given object is equal toself(useseql?). -
include?(aliased asmember?): Returns whether a given object is an element ofself.
Methods for Iterating
-
%: Requires argumentn; calls the block with eachn-th element ofself. -
each: Calls the block with each element ofself. -
step: Takes optional argumentn(defaults to 1); calls the block with eachn-th element ofself.
Methods for Converting
-
inspect: Returns a string representation ofself(usesinspect). -
to_a(aliased asentries): Returns elements ofselfin an array.
Methods for Working with JSON
-
::json_create: Returns a newRangeobject constructed from the given object. -
as_json: Returns a 2-element hash representingself.
To make these methods available:
require 'json/add/range'
Public Class Methods
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/range.rb, line 9 def self.json_create(object) new(*object['a']) end
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 608
def initialize: (Elem from, Elem to, ?boolish exclude_end) -> void
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"]
Public Instance Methods
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 263
def %: (Numeric | int n) -> Enumerator[Elem, self]
| (Numeric | int n) { (Elem element) -> void } -> self
Same as step (but doesn’t provide default value for n). The method is convenient for experssive producing of Enumerator::ArithmeticSequence.
array = [0, 1, 2, 3, 4, 5, 6] # slice each second element: seq = (0..) % 2 #=> ((0..).%(2)) array[seq] #=> [0, 2, 4, 6] # or just array[(0..) % 2] #=> [0, 2, 4, 6]
Note that due to operator precedence in Ruby, parentheses are mandatory around range in this case:
(0..7) % 2 #=> ((0..7).%(2)) -- as expected 0..7 % 2 #=> 0..1 -- parsed as 0..(7 % 2)
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 296
def ==: (untyped obj) -> bool
Returns true if and only if:
-
otheris a range. -
other.begin == self.begin. -
other.end == self.end. -
other.exclude_end? == self.exclude_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?.
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 335
def ===: (untyped obj) -> bool
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"
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/range.rb, line 31 def as_json(*) { JSON.create_id => self.class.name, 'a' => [ first, last, exclude_end? ] } end
Methods Range#as_json and Range.json_create may be used to serialize and deserialize a Range object; see Marshal.
Method Range#as_json serializes self, returning a 2-element hash representing self:
require 'json/add/range' x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]}
Method JSON.create deserializes such a hash, returning a Range object:
Range.json_create(x) # => 1..4 Range.json_create(y) # => 1...4 Range.json_create(z) # => "a".."d"
Methods Range#as_json and Range.json_create may be used to serialize and deserialize a Range object; see Marshal.
Method Range#as_json serializes self, returning a 2-element hash representing self:
require 'json/add/range' x = (1..4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, false]} y = (1...4).as_json # => {"json_class"=>"Range", "a"=>[1, 4, true]} z = ('a'..'d').as_json # => {"json_class"=>"Range", "a"=>["a", "d", false]}
Method JSON.create deserializes such a hash, returning a Range object:
Range.json_create(x) # => 1..4 Range.json_create(y) # => 1...4 Range.json_create(z) # => "a".."d"
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 348
def begin: () -> Elem
Returns the object that defines the beginning of self.
(1..4).begin # => 1 (..2).begin # => nil
Related: Range#first, Range#end.
() → ::Enumerator[Elem, Elem?]
() { (Elem) → (true | false) } → Elem?
() { (Elem) → ::Integer } → Elem?
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 358
def bsearch: () -> ::Enumerator[Elem, Elem?]
| () { (Elem) -> (true | false) } -> Elem?
| () { (Elem) -> ::Integer } -> Elem?
Returns an element from self selected by a binary search.
See Binary Searching.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1017
def count: () -> (Integer | Float)
| (untyped) -> Integer
| () { (Elem) -> boolish } -> Integer
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.
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 486
def cover?: (untyped obj) -> bool
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
selfis larger than its end value. -
An internal call to
<=>returnsnil; that is, the operands are not comparable.
Beginless ranges cover all values of the same type before the end, excluding the end for exclusive ranges. Beginless ranges cover ranges that end before the end of the beginless range, or at the end of the beginless range for inclusive ranges.
(..2).cover?(1) # => true (..2).cover?(2) # => true (..2).cover?(3) # => false (...2).cover?(2) # => false (..2).cover?("2") # => false (..2).cover?(..2) # => true (..2).cover?(...2) # => true (..2).cover?(.."2") # => false (...2).cover?(..2) # => false
Endless ranges cover all values of the same type after the beginning. Endless exclusive ranges do not cover endless inclusive ranges.
(2..).cover?(1) # => false (2..).cover?(3) # => true (2...).cover?(3) # => true (2..).cover?(2) # => true (2..).cover?("2") # => false (2..).cover?(2..) # => true (2..).cover?(2...) # => true (2..).cover?("2"..) # => false (2...).cover?(2..) # => false (2...).cover?(3...) # => true (2...).cover?(3..) # => false (3..).cover?(2..) # => false
Ranges that are both beginless and endless cover all values and ranges, and return true for all arguments, with the exception that beginless and endless exclusive ranges do not cover endless inclusive ranges.
(nil...).cover?(Object.new) # => true (nil...).cover?(nil...) # => true (nil..).cover?(nil...) # => true (nil...).cover?(nil..) # => false (nil...).cover?(1..) # => false
Related: Range#include?.
() { (Elem arg0) → untyped } → self
() → ::Enumerator[Elem, self]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 503
def each: () { (Elem arg0) -> untyped } -> self
| () -> ::Enumerator[Elem, self]
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.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 518
def end: () -> Elem
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.
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"]
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1155
def eql?: (untyped obj) -> bool
Returns true if and only if:
-
otheris a range. -
other.begin.eql?(self.begin). -
other.end.eql?(self.end). -
other.exclude_end? == self.exclude_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#==.
() → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 531
def exclude_end?: () -> bool
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
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 554
def first: () -> Elem
| (Integer n) -> ::Array[Elem]
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
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 566
def hash: () -> Integer
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.
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 593
def include?: (untyped obj) -> bool
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?.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 629
def inspect: () -> String
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.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 664
def last: () -> Elem
| (Integer n) -> ::Array[Elem]
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
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 747
def max: ...
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:
-
selfis a endless range:(1..). -
A block is given and
selfis a beginless range.
Related: Range#min, Range#minmax.
(untyped obj) → bool
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1185
def member?: (untyped obj) -> bool
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?.
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 829
def min: ...
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:
-
selfis a beginless range:(..4). -
A block is given and
selfis an endless range.
Related: Range#max, Range#minmax.
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 875
def 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
ais smaller thanb. -
Zero if
aandbare equal. -
Positive if
ais larger thanb.
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.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 941
def overlap?: (Range[untyped]) -> bool
Returns true if range overlaps with self, false otherwise:
(0..2).overlap?(1..3) #=> true (0..2).overlap?(3..4) #=> false (0..).overlap?(..0) #=> true
With non-range argument, raises TypeError.
(1..3).overlap?(1) # TypeError
Returns false if an internal call to <=> returns nil; that is, the operands are not comparable.
(1..3).overlap?('a'..'d') # => false
Returns false if self or range is empty. “Empty range” means that its begin value is larger than, or equal for an exclusive range, its end value.
(4..1).overlap?(2..3) # => false (4..1).overlap?(..3) # => false (4..1).overlap?(2..) # => false (2...2).overlap?(1..2) # => false (1..4).overlap?(3..2) # => false (..4).overlap?(3..2) # => false (1..).overlap?(3..2) # => false (1..2).overlap?(2...2) # => false
Returns false if the begin value one of self and range is larger than, or equal if the other is an exclusive range, the end value of the other:
(4..5).overlap?(2..3) # => false (4..5).overlap?(2...4) # => false (1..2).overlap?(3..4) # => false (1...3).overlap?(3..4) # => false
Returns false if the end value one of self and range is larger than, or equal for an exclusive range, the end value of the other:
(4..5).overlap?(2..3) # => false (4..5).overlap?(2...4) # => false (1..2).overlap?(3..4) # => false (1...3).overlap?(3..4) # => false
Note that the method wouldn’t make any assumptions about the beginless range being actually empty, even if its upper bound is the minimum possible value of its type, so all this would return true:
(...-Float::INFINITY).overlap?(...-Float::INFINITY) # => true (..."").overlap?(..."") # => true (...[]).overlap?(...[]) # => true
Even if those ranges are effectively empty (no number can be smaller than -Float::INFINITY), they are still considered overlapping with themselves.
Related: Range#cover?.
() { (Elem) → void } → self
() → ::Enumerator[Elem, self]
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 961
def reverse_each: () { (Elem) -> void } -> self
| () -> ::Enumerator[Elem, self]
With a block given, passes each element of self to the block in reverse order:
a = [] (1..4).reverse_each {|element| a.push(element) } # => 1..4 a # => [4, 3, 2, 1] a = [] (1...4).reverse_each {|element| a.push(element) } # => 1...4 a # => [3, 2, 1]
With no block given, returns an enumerator.
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 983
def size: () -> (Integer | Float | nil)
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
If self is not iterable, raises an exception:
(0.5..2.5).size # TypeError (..1).size # TypeError
Related: Range#count.
(?Numeric | int) → Enumerator[Elem, self]
(?Numeric | int) { (Elem element) → void } → self
(untyped) → Enumerator[Elem, self]
(untyped) { (Elem element) → void } → self
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1099
def step: (?Numeric | int) -> Enumerator[Elem, self]
| (?Numeric | int) { (Elem element) -> void } -> self
| (untyped) -> Enumerator[Elem, self]
| (untyped) { (Elem element) -> void } -> self
Iterates over the elements of range in steps of s. The iteration is performed by + operator:
(0..6).step(2) { puts _1 } #=> 1..5 # Prints: 0, 2, 4, 6 # Iterate between two dates in step of 1 day (24 hours) (Time.utc(2022, 2, 24)..Time.utc(2022, 3, 1)).step(24*60*60) { puts _1 } # Prints: # 2022-02-24 00:00:00 UTC # 2022-02-25 00:00:00 UTC # 2022-02-26 00:00:00 UTC # 2022-02-27 00:00:00 UTC # 2022-02-28 00:00:00 UTC # 2022-03-01 00:00:00 UTC
If + step decreases the value, iteration is still performed when step begin is higher than the end:
(0..6).step(-2) { puts _1 } # Prints nothing (6..0).step(-2) { puts _1 } # Prints: 6, 4, 2, 0 (Time.utc(2022, 3, 1)..Time.utc(2022, 2, 24)).step(-24*60*60) { puts _1 } # Prints: # 2022-03-01 00:00:00 UTC # 2022-02-28 00:00:00 UTC # 2022-02-27 00:00:00 UTC # 2022-02-26 00:00:00 UTC # 2022-02-25 00:00:00 UTC # 2022-02-24 00:00:00 UTC
When the block is not provided, and range boundaries and step are Numeric, the method returns Enumerator::ArithmeticSequence.
(1..5).step(2) # => ((1..5).step(2)) (1.0..).step(1.5) #=> ((1.0..).step(1.5)) (..3r).step(1/3r) #=> ((..3/1).step((1/3)))
Enumerator::ArithmeticSequence can be further used as a value object for iteration or slicing of collections (see Array#[]). There is a convenience method % with behavior similar to step to produce arithmetic sequences more expressively:
# Same as (1..5).step(2) (1..5) % 2 # => ((1..5).%(2))
In a generic case, when the block is not provided, Enumerator is returned:
('a'..).step('b') #=> #<Enumerator: "a"..:step("b")> ('a'..).step('b').take(3) #=> ["a", "ab", "abb"]
If s is not provided, it is considered 1 for ranges with numeric begin:
(1..5).step { p _1 } # Prints: 1, 2, 3, 4, 5
For non-Numeric ranges, step absence is an error:
(Time.utc(2022, 3, 1)..Time.utc(2022, 2, 24)).step { p _1 } # raises: step is required for non-numeric ranges (ArgumentError)
For backward compatibility reasons, String ranges support the iteration both with string step and with integer step. In the latter case, the iteration is performed by calculating the next values with String#succ:
('a'..'e').step(2) { p _1 } # Prints: a, c, e ('a'..'e').step { p _1 } # Default step 1; prints: a, b, c, d, e
Source
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1198
def to_a: ...
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"]
(?JSON::State? state) → String
Source
# File vendor/bundle/ruby/4.0.0/gems/json-2.21.0/lib/json/add/range.rb, line 51 def to_json(*args) as_json.to_json(*args) end
Returns a JSON string representing self:
require 'json/add/range' puts (1..4).to_json puts (1...4).to_json puts ('a'..'d').to_json
Output:
{"json_class":"Range","a":[1,4,false]}
{"json_class":"Range","a":[1,4,true]}
{"json_class":"Range","a":["a","d",false]}
Returns a JSON string representing self:
require 'json/add/range' puts (1..4).to_json puts (1...4).to_json puts ('a'..'d').to_json
Output:
{"json_class":"Range","a":[1,4,false]}
{"json_class":"Range","a":[1,4,true]}
{"json_class":"Range","a":["a","d",false]}
# File vendor/bundle/ruby/4.0.0/gems/rbs-4.0.3/core/range.rbs, line 1123
def to_s: () -> 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.