Neu: Das englische Ruby on Rails 4.0 Buch.

2.9. Schleifen (Loops)

Es gibt verschiedene Arten, Schleifen in Ruby zu realisieren. Dabei kommt im Rails-Umfeld vor allen Dingen die Iterator-Variante häufig zum Einsatz.

while und until

Eine While-Schleife sieht abstrakt wie folgt aus:
while ausdruck do
  programm
end

Anmerkung

Das do nach dem ausdruck ist optional. Oft sieht man auch:
while ausdruck
  programm
end
Und praktisch wie in folgendem irb-Beispiel:
1.9.3p194 :001:0> i = 0             # i wird auf 0 gesetzt
=> 0
1.9.3p194 :002:0> while i < 3 do   # Schleife
1.9.3p194 :003:1>   puts i          # i wird ausgegeben
1.9.3p194 :004:1>   i = i + 1       # i wird um 1 erhöht
1.9.3p194 :005:1> end               # Ende der Schleife
0
1
2
=> nil
1.9.3p194 :006:0> exit
Until-Schleifen werden ähnlich aufgebaut:
until ausdruck
  programm
end
Auch hier das irb-Beispiel:
sw@debian:~/sandbox$ irb
1.9.3p194 :001:0> i = 5
=> 5
1.9.3p194 :002:0> until i == 0
1.9.3p194 :003:1> i = i - 1
1.9.3p194 :004:1> puts i
1.9.3p194 :005:1> end
4
3
2
1
0
=> nil
1.9.3p194 :006:0> exit

Blöcke (Blocks) und Iteratoren (Iterators)

Block und Iterator gehören zu den Lieblingswörtern vieler Ruby-Programmierer. Jetzt zeige ich Ihnen mal warum.
Bei der Schleife
5.times { |i| puts i }
ist i der Iterator und puts i der Block.
Das Ganze kann aber auch in der folgenden Syntax ausgedrückt werden:
5.times do |i|
  puts i
end

Iteratoren (Iterators)

Iteratoren sind nichts weiter als eine bestimmte Art von Methoden. (Das englische Wort iterate heißt wiederholen.) Bei der Klasse Fixnum gibt es zum Beispiel den Iterator times. Mal schauen, was uns ri dazu als Hilfe anbietet:
sw@debian:~/sandbox$ ri Fixnum.times
= Fixnum.times

(from ruby site)
=== Implementation from Integer
------------------------------------------------------------------------------
  int.times {|i| block }  ->  self
  int.times               ->  an_enumerator

------------------------------------------------------------------------------

Iterates block int times, passing in values from zero to int - 1.

If no block is given, an enumerator is returned instead.

  5.times do |i|
    print i, " "
  end

produces:

  0 1 2 3 4

sw@debian:~/sandbox$ 
Und dort steht auch direkt ein schönes Beispiel, das wir im irb ausprobieren:
sw@debian:~/sandbox$ irb
1.9.3p194 :001:0> 5.times do |i|
1.9.3p194 :002:1* puts i
1.9.3p194 :003:1> end
0
1
2
3
4
=> 5
1.9.3p194 :004:0> exit
Und es gibt auch noch eine Einzeilen-Schreibweise für kleine Blöcke:
sw@debian:~/sandbox$ irb
1.9.3p194 :001:0> 5.times { |i| puts i }
0
1
2
3
4
=> 5
1.9.3p194 :002:0> exit
Ein Iterator muss übrigens dem Block nicht zwangsläufig eine Variable übergeben:
sw@debian:~/sandbox$ irb
1.9.3p194 :001:0> 5.times { puts 'Das blaue Haus.' }
Das blaue Haus.
Das blaue Haus.
Das blaue Haus.
Das blaue Haus.
Das blaue Haus.
=> 5
1.9.3p194 :002:0> exit

Blöcke (Blocks)

Ein Block ist nichts anderes, als das von einem Iterator ausgelöste Programm. Im Block hat man Zugriff auf die vom Iterator übergebene(n) lokale(n) Variable(n).

Methode upto

Neben times gibt es noch die Methode upto, um leicht eine Schleife zu realisieren. ri gibt uns auch hier ein schönes Beispiel:
sw@debian:~/sandbox$ ri Fixnum.upto
= Fixnum.upto

(from ruby site)
=== Implementation from Integer
------------------------------------------------------------------------------
  int.upto(limit) {|i| block }  ->  self
  int.upto(limit)               ->  an_enumerator

------------------------------------------------------------------------------

Iterates block, passing in integer values from int up to and
including limit.

If no block is given, an enumerator is returned instead.

  5.upto(10) { |i| print i, " " }

produces:

  5 6 7 8 9 10

sw@debian:~/sandbox$ 

Autor

Stefan Wintermeyer