class Range

Ein Range-Objekt repräsentiert eine Sammlung von Werten, die zwischen gegebenen Anfangs- und Endwerten liegen.

Sie können ein Range-Objekt explizit mit

Beginnlose Bereiche

Ein *beginnloser* *Bereich* hat einen bestimmten Endwert, aber einen nil-Anfangswert. Ein solcher Bereich enthält alle Werte bis zum Endwert.

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

Ein beginnloser Bereich kann zum Slicen eines Arrays verwendet werden

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]

Die Methode each für einen beginnlosen Bereich löst eine Ausnahme aus.

Endlose Bereiche

Ein *endloser* *Bereich* hat einen bestimmten Anfangswert, aber einen nil-Endwert. Ein solcher Bereich enthält alle Werte ab dem Anfangswert.

r = (1..)         # => 1..
r.end             # => nil
r.include?(50)    # => true

Range.new(1, nil) # => 1..

Das Literal für einen endlosen Bereich kann mit zwei oder drei Punkten geschrieben werden. Der Bereich hat in beiden Fällen die gleichen Elemente. Beachten Sie jedoch, dass die beiden nicht gleich sind

r0 = (1..)           # => 1..
r1 = (1...)          # => 1...
r0.begin == r1.begin # => true
r0.end == r1.end     # => true
r0 == r1             # => false

Ein endloser Bereich kann zum Slicen eines Arrays verwendet werden

a = [1, 2, 3, 4]
r = (2..) # => 2..
a[r]      # => [3, 4]

Die Methode each für einen endlosen Bereich ruft den gegebenen Block unendlich oft auf

a = []
r = (1..)
r.each do |i|
  a.push(i) if i.even?
  break if i > 10
end
a # => [2, 4, 6, 8, 10]

Ein Bereich kann sowohl beginnlos als auch endlos sein. Für literale beginnlose und endlose Bereiche muss mindestens der Anfang oder das Ende des Bereichs als expliziter nil-Wert angegeben werden. Es wird empfohlen, einen expliziten nil-Anfang und ein nil-Ende zu verwenden, da dies das ist, was Ruby für Range#inspect verwendet.

(nil..)    # => (nil..nil)
(..nil)    # => (nil..nil)
(nil..nil) # => (nil..nil)

Bereiche und andere Klassen

Ein Objekt kann in einen Bereich aufgenommen werden, wenn seine Klasse die Instanzmethode <=> implementiert. Zu den Ruby-Kernklassen, die dies tun, gehören Array, Complex, File::Stat, Float, Integer, Kernel, Module, Numeric, Rational, String, Symbol und Time.

Beispiel

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

Ein Bereich kann nur iteriert werden, wenn seine Elemente die Instanzmethode succ implementieren. Zu den Ruby-Kernklassen, die dies tun, gehören Integer, String und Symbol (nicht aber die anderen oben genannten Klassen).

Iterator-Methoden umfassen

Beispiel

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

Bereiche und benutzerdefinierte Klassen

Eine benutzerdefinierte Klasse, die in einem Bereich verwendet werden soll, muss die Instanzmethode <=> implementieren; siehe Integer#<=>. Um die Iteration zu ermöglichen, muss sie auch die Instanzmethode succ implementieren; siehe Integer#succ.

Die unten stehende Klasse implementiert sowohl <=> als auch succ und kann daher sowohl zur Konstruktion von Bereichen als auch zur Iteration über sie verwendet werden. Beachten Sie, dass das Modul Comparable enthalten ist, damit die Methode == auf Basis von <=> definiert wird.

# 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

Was gibt es hier

Zunächst, was anderswo steht. Klasse Range

Hier bietet die Klasse Range Methoden, die nützlich sind für

Methoden zum Erstellen eines Bereichs

Methoden zum Abfragen

Methoden zum Vergleichen

Methoden zur Iteration

Methoden zur Konvertierung

Methoden für die Arbeit mit JSON

Um diese Methoden verfügbar zu machen

require 'json/add/range'