Be aware of the possibility of an infinite loop.
An wie vielen Stellen erhält man eine solche oder eine ähnliche Warnung? Endlosschleifen lassen sich doch viel einfacher als aus Versehen generieren:
1
2
3
|
loop do
#Ich werde niemals enden...
end |
Nun gut, so weit also zur Endlosschleife, die man nicht mit Konstrukten wie while true generieren muss. Ruby kennt einige Arten von Schleifen:
while
Syntax
while [expr] [do]
#Code...
end
Beschreibung
Die Schleife läuft, solange ein Ausdruck (expr) true ergibt. Das Schlüsselwort do ist optional, alternativ kann man auch die geschweifte Klammer ({}) verwenden (Priorität beachten!).
1
2
3
4
|
a = 0
while a < 9
a += 1
end |
until
Syntax
until [expr] [do]
#Code...
end
Beschreibung
Diese Schleife ist das Gegenteil von while. Sie läuft, solange ein Ausdruck false ist, bzw. bis er true ergibt. Auch hier ist do optional.
1
2
3
4
|
a = 0
until a >= 9
a += 1
end |
Anhängsel
Sowohl while als auch until lassen sich als Ausdrucksanhängsel benutzen:
1
2
3
4
|
a = 0
a += 1 while a < 9
a = 0
a += 1 until a >= 9 |
for
Syntax
for [element] in [objekt] [do]
#Code...
end
Beschreibung
Sofern ein Objekt ein Enumerable ist, geht das iterierende for dieses Objekt Stück für Stück durch. In der Regel entspricht dies allerdings einem Aufruf der Methode each eines Objekts. do ist optional.
1
2
3
4
5
6
7
8
|
ary = [1, 2, 3]
ary.each do |element|
puts element
end
#Ist das gleiche wie
for element in ary do
puts element
end |
Gültigkeitsbereiche
Die Schleifen while, until und for sind zugleich eine Besonderheit in Ruby: Sie besitzen keinen eigenen Gültigkeitsbereich. Das ist sehr ungewöhnlich, da für gewöhnlich jeder Codeblock ein Bereich für sich ist, aber Schleifen handhaben das anders.
1
2
3
4
5
6
|
x = 0
while x < 2
y = "Lokal?"
x += 1
end
puts y #=> Lokal? |
Andere Schleifen
Zusätzlich zu diesen Grundschleifen (die bis auf for eigentlich nur selten benutzt werden) bieten viele Objekte eigene Schleifen an, wie zum Beispiel String each_byte. Die populärsten und vermutlich meist benutzten bietet die Klasse Fixnum, es sind die Methoden times, downto und upto.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
3.times{|zahl| puts zahl}
#=> 0
#=> 1
#=> 2
0.upto(2){|zahl| puts zahl}
#=> 0
#=> 1
#=> 2
2.downto(0) do |zahl|
puts zahl
end
#=> 2
#=> 1
#=> 0 |
Rekursion
Neben der herkömmlichen Art, Schleifen zu genererieren, besteht die Möglichkeit der Rekursion. Dabei ruft sich eine Methode innerhalb ihres Codes selbst auf:
1
2
3
4
5
|
def potenzieren(basis, exponent = 2)
return exponent == 0 ? 1 : basis * potenzieren(basis, exponent - 1)
end
puts "3 hoch 3 ergibt #{potenzieren(3, 3)}. "
#=> 3 hoch 3 ergibt 27. |
Stoppen und anderes
Man sollte wissen, wie jede Schleife gestoppt werden kann. Wenig bekannt dabei ist, dass man den folgenden Schlüsselwörtern einen Rückgabewert mitgeben kann, z.B. break(3).
break
Das Schlüsselwort break bricht eine Schleife oder einen Iterator ohne zu fragen ab.
1
2
3
4
5
6
|
a = 1
loop do
a -= 1
break if a < -5
end
#a ist jetzt -6. |
redo
retry hat, wie oft fälschlich angenommen wird, nichts mit Schleifen zu tun, siehe dazu Exception. Was gemeint ist, ist in der Regel redo, was bewirkt, dass der aktuelle Schleifendurchlauf vom Anfang ab noch einmal wiederholt wird.
1
2
3
4
5
6
|
a = 0
3.times do
a += 1
redo if a == 2
end
#a ist jetzt 4. |
next
Daneben gibt es noch next, der aktuelle Durchlauf wird an dieser Stelle abgebrochen und der nächste gestartet.
1
2
3
4
5
|
3.times do
next if a == 2
a += 1
end
#a ist jetzt 2. |
Siehe auch