Ruby-Programmierung: Kontrollstrukturen
Zurück zum Inhaltsverzeichnis.
Diese Seite beschäftigt sich mit Kontrollstrukturen. Um etwas auf die Frage einzugehen, was eine Programmiersprache ausmacht und warum andere Sprachen keine Programmiersprachen sind. Die wichtigsten beiden Eigenschaften einer Programmiersprache sind, Quellcode wiederholt und optional ausführen zu können. Für verschiedene Sprachen existieren unterschiedliche Implementierungen dieser beiden Grundlagen. Ruby kennt Verzweigungen, zur optionalen Ausführung von Programmtext. Es lassen sich innerhalb des Programmflusses Entscheidungen treffen und auf sie reagieren. Zum Beispiel, wenn eine falsche Benutzereingabe behandelt werden muss.
Für die wiederholte Ausführung von Programmteilen gibt es in Ruby drei wesentliche Möglichkeiten, mit aufsteigender Präferenz: Schleifen, Rekursionen und Iterationen. An dieser Stelle wird nur auf Schleifen eingegangen. Rekursionen sind Teil des Kapitels Methoden, während Iterationen im zweiten Teil des Buches thematisiert werden.
Verzweigungen
[Bearbeiten]Für die Behandlung von Verzweigungen ist es zunächst nötig sich mit Vergleichs- und Logikoperatoren zu beschäftigen. Es geht darum Daten auf etwas hin zu prüfen, zum Beispiel, ob eine Zahl größer ist als ein erwarteter Wert und die Ergebnisse verschiedener Prüfungen logisch zu kombinieren. Die folgende Tabelle gibt eine Übersicht über die vorhandenen Vergleichs- und Logikoperatoren, wobei die einzelne Funktionalität in Abhängigkeit von den übergebenen Typen variieren kann.
Operator | Erklärung |
---|---|
== |
Prüft auf Gleichheit |
< |
Kleiner als |
> |
Größer als |
<= |
Kleiner gleich |
>= |
Größer gleich |
! |
logisches nicht |
&& |
logisches und |
|| |
logisches oder |
Die eigentliche Verzweigung im Programmtext erfolgt über die Schlüsselwörter if
, elsif
, else
und unless
, denen ein Wahrheitswert übergeben wird, der typischerweise durch oben betrachtete Operatoren ermittelt wird. Das folgende Skript gibt dabei Beispiele für verschiedene Anwendungsfälle. Es gilt zu beachten, dass elsif
ohne 'e' geschrieben wird.
a = 2
b = 3
if a > b
puts "a ist groesser"
elsif b == 10
puts "b ist zehn!"
else
puts "Standard"
end
Jede Kontrollanweisung leitet dabei einen Block ein, in dem sie gilt. Beendet wird ein Block mit dem Schlüsselwort end
. Beim Ausführen des Skripts wird der Text "Standard" ausgegeben, da weder a
größer als b
, noch b
gleich zehn ist. Die Anweisung unless STATEMENT
ist äuqivalent zur Anweisung if !STATEMENT
, der Programmblock wird also nur Ausgeführt, wenn die Bedingung nicht erfüllt wird. In Ruby sind nur die Werte nil
und false
logisch falsch. Insbesondere Programmierer, die bereits C oder eine ähnliche Sprache können, müssen an dieser Stelle aufpassen, dass eine 0 logisch wahr ist.
Eine Möglichkeit seinen Programmtext stilistisch zu verbessern ist es, eine Kontrollabfrage hinter den eigentlichen Kontrollblock zu schreiben. Dieser Kontrollblock besteht dann lediglich aus einer Zeile, nämlich allem, was vor dem entsprechenden Schlüsselwort steht. Das Skript von oben lässt sich also auch in kürzerer Form schreiben. Dabei gilt zu beachten, dass inbesondere die fünfte Zeile deutlich weniger lesbar ist, als die entsprechende Zeile im obigen Skript.
a = 2
b = 3
puts "a ist groesser" if a > b
puts "b ist zehn!" if b == 10
puts "Standard" unless a > b || b == 10
Eine weitere Möglichkeit ist das Wählen der Verzweigung mit case ... when
. Mit case
wählt man aus, was man überprüfen möchte und mit when
wechselt man die Fälle. Wie bei if
-Anweisungen ist es Möglich mit else
einen Default-Fall zu erzeugen, falls sonst nichts zutrifft. Die gleiche Behandlung mehrerer Fälle erfolgt durch Trennung mit einem Komma. Zum Beispiel:
a = 2
case a
when 1
puts "Eins!"
when 2, 3
puts "Zwei oder Drei!"
else
puts "Irgendetwas!"
end
Schleifen
[Bearbeiten]Die einfachste Form einer Schleife ist die Endlosschleife. Sie entsteht oftmals als Folge von Programmierfehlern, kann aber unter Umständen auch gewünscht sein, wenn sie zum Beispiel in Folge einer Benutzereingabe abgebrochen wird. Somit handelt es sich nicht um eine echte Endlosschleife.
loop do
input = gets
break if input == "exit\n"
puts "Ihre Eingabe lautete: " + input
next
puts "Diese Zeile wird nie ausgegeben"
end
Wenn Sie dieses Skript starten und ein paar Eingaben tätigen, werden Sie feststellen, dass Sie beliebig oft Eingaben tätigen können und diese ausgegeben werden. In dem Skript finden sich die Schlüsselwörter next
und break
. Mit break
verlässt man die aktuelle Schleife, in diesem Fall ist also if eingabe == "exit\n"
die Abbruchbedingung für die Pseudoendlosschleife. Es sei noch einmal betont, dass eine wirkliche Endlosschleife selten erwünscht ist, da man das Programm nur noch extern beenden kann. Während man mit break
also hinter die Schleife springt, springt next
an den Anfang der Schleife, es steht einfach für den nächsten Schleifendurchlauf. Alle Formen von Schleifen sind ineinander umformbar, doch ist es offensichtlich, dass ein stetiges Prüfen der Abbruchbedingung am Anfang einer Endlosschleife syntaktisch nicht schön ist, deswegen gibt es zwei weitere Schleifenschlüsselwörter. Im folgenden Skript ist eine while
- bzw. until
-Schleife implementiert, deren Funktion dem eben dargestellten Skript gleicht. Die Schlüsselwörter while
und until
verhalten sich zueinander wie if
und unless
.
input = ""
until input == "exit\n"
input = gets
puts input
end
Eine weitere Möglichkeit eine Schleife zu bilden ist for
. Diese Schleife kommt dabei nicht zu derselben Bedeutung wie ihr Synonym in C oder Java, sondern wird weitaus weniger eingesetzt. Sie wird insbesondere durch die Iterator-Methoden verdrängt, die eine weitaus mächtigere Möglichkeit bieten, Arrays und andere Datenstrukturen zu behandeln. Trotzdem sei eine for
-Schleife der Vollständigkeit halber hier erwähnt, denn sie kann notwendig werden, wenn man eigene Iteratoren definieren möchte.
for i in (0..10)
puts i
end
Bei dem Konstrukt (0..10)
handelt es sich um eine Range, also alle Zahlen zwischen 0 und 10. Ranges gibt es in einer inklusiven Variante mit zwei Punkten und einer exklusiven Variante mit drei Punkten.
Fakultät
[Bearbeiten]Die Fakultät ist eine mathematische Funktion auf den natürlichen Zahlen. Das Implementieren der Fakultät ist eine Standardaufgabe beim Lernen einer Programmiersprache, da man dafür die auf dieser Seite gelernten Kontrollstrukturen verwenden kann und man somit vertraute Strukturen aus anderen Programmiersprachen schnell wiedererkennt, oder auf die Unterschiede stößt. Die Fakultät ist wie folgt definiert: , außerdem gilt .
# fakultaet.rb
# Ermittelt die Fakultät einer vom Benutzer eingegebenen Zahl.
eingabe = ""
until eingabe == "exit\n"
eingabe = gets
n = eingabe.to_i
if n < 0
puts "Fehlerhafte Eingabe!"
next
elsif n == 0
ergebnis = 1
else
ergebnis = 1
until n == 1
ergebnis *= n
n -= 1
end
end
puts "Die berechnete Fakultät ist: " + ergebnis.to_s unless eingabe == "exit\n"
end
Wieder sollte Ihnen vieles vertraut vorkommen. Zur Erklärung des Algorithmus gibt es lediglich zu sagen, dass ergebnis
mit 1 initialisiert wird und solange mit dem herunterzählenden n
multipliziert wird, bis dieses den Wert 1 hat und die Fakultät fertig berechnet ist.
- Zeile 07:
.to_i
dient der Typumwandlung zu einer natürlichen Zahl. - Zeile 08: Abfangen einer fehlerhaften, negativen Eingabe.
- Zeile 16:
ergebnis *= n
ist äquivalent zuergebnis = ergebnis * n
? :
[Bearbeiten]Für das häufig vorkommende if
und else
gibt es eine Kurzschreibweise mit ? :
. Dieser kryptische Operator stammt aus der Programmiersprache C, wo er hinzugefügt wurde, um Parameter für Funktionen auszuwählen. Er ist mit Vorsicht anzuwenden, da er den Lesefluss des Programms deutlich einschränken kann, was der Philosophie eines leicht lesbaren Programmtextes in Ruby zuwider ist. Er kann jedoch insbesondere bei kurzen Verzweigungen vorteilhaft sein. Folgende beiden Programmabschnitte sind dabei äquivalent:
# 1. Variante mit if und else
if 1 == 2
puts "Etwas ist seltsam."
else
puts "Hier ist alles korrekt."
end
# 2. Variante mit ? :
1 == 2 ? puts("Eins ist gleich zwei!") : puts("Nein, alles ist richtig.")