Ranges stellen ein Intervall zwischen zwei Werten dar.
Die häufigsten Typen, die Ranges unterstützen, sind Integer und String.
Du kannst sie für vieles verwenden: um schnell eine Sammlung zu erstellen, Strings zu zerlegen, zu prüfen, ob ein Wert in einem Range liegt, und für Iterationen.
Erstellt werden sie mit dem Range-Operator .. oder ... (einschließlich bzw. ausschließlich).
1..5 # => 1..5
1...5 # => 1...5
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
Der Grund für zwei Range-Operatoren ist, dass du damit Ranges erstellen kannst, die den Endwert einschließen oder ausschließen. Das ist zum Beispiel nützlich, wenn du mit Indizes arbeitest, die bei null beginnen.
Ranges lassen sich auch mit dem Range-Initialisierer erstellen.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Wenn du in Ruby mit den Range-Operatoren .. oder ... einen Range erstellst und eine Methode darauf aufrufen willst, musst du den Range in runde Klammern setzen.
Sonst wird die Methode nämlich auf dem zweiten Argument des Range-Operators aufgerufen.
(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)
Wenn du einen String zerlegen willst, kannst du mit dem Range-Operator einen Teilstring ermitteln. Dazu erstellst du einen Range mit dem Start- und Endindex des Teilstrings.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
Du kannst auch negative Indizes verwenden, um den Teilstring vom Ende des Strings aus zu ermitteln.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
Ranges haben eine Reihe von Methoden, mit denen du arbeiten kannst. Zum Beispiel kannst du damit die Summe aller Werte im Range berechnen oder prüfen, ob ein Wert im Range enthalten ist.
| Methode | Beschreibung | Beispiel |
|---|---|---|
sum |
Gibt die Summe aller Werte im Range zurück | (1..5).sum # => 15 |
size |
Gibt die Größe des Ranges zurück | (1..5).size # => 5 |
include? |
Gibt true zurück, wenn der Range den angegebenen Wert enthält, sonst false
|
(1..5).include?(3) # => true |
Ein Range kann endlos sein oder keinen Anfang haben.
Bei einem endlosen Range ist der Endwert nil, bei einem Range ohne Anfang der Startwert. Beim Definieren des Ranges kannst du das nil aber weglassen.
Ranges ohne Anfang und endlose Ranges sind nützlich, wenn du zum Beispiel einen String vom Anfang oder bis zum Ende zerlegen willst.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Wenn du einen endlosen Range nicht auf einer Sammlung verwendest, kann er eine endlose Sequenz erzeugen, falls du nicht vorsichtig bist.
Auch Strings können in Ranges verwendet werden. So bekommst du ein Intervall von Strings zwischen zwei Strings. Bei bestimmten Strings kann das Verhalten etwas unerwartet sein, also sei vorsichtig.
"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]
Ruby erlaubt es dir, eigene Objekte in Ranges zu verwenden. Voraussetzung dafür ist, dass das Objekt Folgendes implementiert:
Comparable einbindetsucc verfügt<=> verfügtDiese Methoden sorgen dafür, dass der Range über das Objekt iterieren und die Objekte im Range vergleichen kann.
class Foo
include Comparable
attr_reader :value
def initialize(value)
@value = value
end
def succ
Foo.new(value + 1)
end
def <=>(other)
value <=> other.value
end
end
(Foo.new(1)..Foo.new(5))
# => #<Foo:0x7f3552bebe70 @value=1>, #<Foo:0x7f3552bebe50 @value=2>, #<Foo:0x7f3552bebe40 @value=3>, #<Foo:0x7f3552bebe30 @value=4>, #<Foo:0x7f3552bebe20 @value=5>