Die Programmiersprache Ruby

Blog| Forum| Wiki  

Bis zu diesem Punkt hast du also Rubys wichtigstes Konzept, EIAO, alles ist ein Objekt, kennengelernt. Ruby bietet sehr viel mehr an Wissenswertem. Eine relativ einfache Tatsache hast du schon kennengelernt: Mathematik. Wie jede ordentliche Programmiersprache kann natürlich auch Ruby Rechnungen mit allen möglichen (und unmöglichen sprich komplexen ;-) ) Zahlen machen. Oder Rückgabewerte von Ausdrücken. Oder Bedingungen. Lerne sie hier alle kennen!

Inhaltsverzeichnis

irb

Aber zunächst möchten wir dich mit Rubys wichtigstem und bekanntestem Testwerkzeug bekannt machen: Der irb. Das Kürzel bedeutet interactive Ruby, also interaktives Ruby. Und genau das ist es auch. Mithilfe der irb kannst du Ruby-Code ausführen und sofort seinen Rückgabewert betrachten; dies ist eine sehr hilfreiche Eigenschaft und führt oft dazu, dass Fehler erkannt werden, die man nicht erwartet hätte. Man kann die irb aber auch einfach dazu benutzen, um »mal eben eine Annahme« zu überprüfen. Gib folgendes in eine Kommandozeile ein, um die irb zu starten:


$ irb

Ist Ruby ordentlich installiert, wird eine irb-Sitzung (engl. Session) gestartet. Tippe ein paar mathematische Ausdrücke ein, um den Effekt zu sehen:

1
2
3
4
5
6
7
8
9
10
11
irb(main):001:0> x = 10
=> 10
irb(main):002:0> x = x + 5
=> 15
irb(main):003:0> x
=> 15
irb(main):004:0> 55 * x
=> 825
irb(main):005:0> x
=> 15
irb(main):006:0>

Deutlich sichtbar zeigt die irb dir jedesmal an, was der Code zurückgibt, den du Zeile für Zeile eingibst. Auch Klassen- und Methodendefinitionen schluckt die irb:

1
2
3
4
5
6
7
irb(main):001:0> def hoch_3(x)
irb(main):002:1> x * x * x
irb(main):003:1> end
=> nil
irb(main):004:0> hoch_3(2)
=> 8
irb(main):005:0>

Nanu...? Was bedeutet denn dieser seltsame nil? nil ist ein spezielles Objekt in Ruby, denn es ist das Objekt, das nicht ist. Vereinfacht: nil meint nichts. Die Betonung liegt hierbei auf dem Wort meint, denn obwohl nil ein Platzhalter ist, der immer dann irgendwo steht, wenn kein Wert zugewiesen wurde, ist es nicht nichts. Der Beweis:

1
2
3
irb(main):005:0> nil.object_id
=> 4
irb(main):006:0>

Schön, aber was macht es denn nun da? Da ist noch nirgends etwas, was eine Zuweisung benötigen würde?
Tja, eben drum. Eine Methodendefinition ist ein valider Ruby-Ausdruck und als solcher muss er etwas zurückgeben. Da es nichts gibt, was sinnvoll zurückzugeben wäre, ist das Resultat nil. Mit nil lassen sich durchaus interessante Spielereien betreiben, aber darauf kommen wir später.

Ausdrücke

Erstmal kommen wir auf den Begriff »valider Ruby-Ausdruck« zurück. Das Fremdwort »valide« ist schnell erklärt, denn ist gleichzusetzen mit »gültig«. Viel interessanter ist die inhaltliche Tatsache, dass jeder Ruby-Ausdruck etwas zurückgibt. Was auch immer du schreibst, es hat ein Ergebnis. Als Beweis sollte dir die irb genügen, denn sie zeigt dir von ausnahmslos jedem Ausdruck sein Ergebnis an. Obwohl du diese Tatsache vermutlich nicht oft benötigen wirst, ist es doch wichtig, sie zu kennen, denn in einigen Situationen kann der Rückgabewert eines Ausdrucks eine Operation völlig verändern. Deshalb sollte man sich immer bewusst sein, was die aktuelle Stelle im Code eigentlich bearbeitet und weitergibt!

Bedingungen

Ja, Bedingungen. Diese kleinen Biester sind das »Gehirn« eines Computers. Obwohl ein Computer nicht in der Lage ist »Was-Wäre-Wenn«-Beziehungen aufzubauen, so kann er doch im konkreten Fall eine Entscheidung treffen. Trifft etwas zu, kannst du ihn anweisen, den einen Weg zu gehen. Trifft es nicht zu, kannst du ihm auch mitteilen, dass er einen anderen gehen soll. In Ruby geschieht dies - wie in den meisten anderen Programmiersprachen auch - mithilfe des englischen Wortes für »Wenn«: if. Um so ein if möglichst akkurat zu machen, stehen dir diverse Möglichkeiten zur Verfügung:

  • Du kannst einfach nur prüfen, ob etwas zutrifft/nicht zutrifft
  • Du kannst die Existenz eines Objektes überprüfen
  • Du kannst mathematische Vergleichsoperatoren benutzen
  • Du kannst mehrere Bedingungen mit »und« sowie »oder« verknüpfen
  • Du kannst Alternativmöglichkeiten angeben

Arbeiten wir dies doch einfach mal der Reihe nach ab:

1. Fall: Prüfung auf Wahrheitsgehalt

Du kannst einfach nur prüfen, ob etwas zutrifft/nicht zutrifft. Trifft etwas zu, ist es »wahr«, engl. true. Trifft es nicht zu, ist es »falsch«, engl. false. Diese beiden Werte, true und false, nennt man nach George Boole boolesche Konstanten (konstant, weil sie sich nie ändern. Wahr ist immer wahr und falsch immer falsch). Angewandt heißt das:

1
2
3
4
5
6
7
8
9
10
irb(main):001:0> if 2.even?
irb(main):002:1> puts "Zwei ist gerade!"
irb(main):003:1> end
Zwei ist gerade!
=> nil
irb(main):004:0> if 3.even?
irb(main):005:1> puts "Morgen geht die Welt unter. Die Mathematik stimmt nicht mehr."
irb(main):006:1> end
=> nil
irb(main):007:0>

Du kannst ebenfalls prüfen, ob etwas nicht zutrifft. Dazu gibt es den logischen Operator not und seine (fast) gleichbedeutende Kurzform !:

1
2
3
4
5
6
irb(main):007:0> if !3.even?
irb(main):008:1> puts "Puh, alles in Ordnung. :)"
irb(main):009:1> end
Puh, alles in Ordnung. :)
=> nil
irb(main):010:0>

2. Fall: Prüfung der Existenz eines Objektes

Du kannst die Existenz eines Objektes überprüfen. Diese Tatsache ist eng mit boolescher Logik verknüpft. Zunächst gilt es zu sagen, dass Ruby »wahr« und »falsch« als Objekte bereit stellt:

1
2
3
4
5
irb(main):001:0> true.object_id
=> 2
irb(main):002:0> false.object_id
=> 0
irb(main):003:0>

Diese Objekte führen bei Einsatz in einer Bedingung immer zum erwarten Ergebnis. Ein true lässt eine Bedingung immer gelingen, ein false immer fehlschlagen. Daneben gibt es in Ruby jedoch soetwas wie einen »indirekten Wahrheitsgehalt«. Dieses mehr oder minder konstruierte Wort beschreibt, wie sich Ruby-Objekte in Bedingungen verhalten. In einem Satz zusammengefasst: Alle Objekte außer false und nil gelten als wahr. . Dass falsch nicht wahr sein kann, ist klar. Warum »nichts« falsch ist, ist aber doch auch relativ einleuchtend, oder? Praktisch angewandt heißt das, dass wir anstatt vieler Prüfungen, ob ein Objekt existiert, einfach schreiben können:

1
2
3
if mein_objekt
  puts "Objekt existiert."
end

Diese Tatsache wird im Umgang mit Instanzvariablen (darauf kommen wir bei der weiteren Besprechung von Klassen) wichtig.

3. Fall: Mathematik

Du kannst mathematische Vergleichsoperatoren benutzen. Der Satz ist relativ selbsterklärend. Betrachte folgendes Beispiel und bilde dir deine Meinung dazu:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
irb(main):001:0> x = 1
=> 1
irb(main):002:0> y = 2
=> 2
irb(main):003:0> if y > x
irb(main):004:1> puts "y größer x!"
irb(main):005:1> end
y größer x!
=> nil
irb(main):006:0> if y < x
irb(main):007:1> puts "y kleiner x!"
irb(main):008:1> end
=> nil
irb(main):009:0> x = x + 10
=> 11
irb(main):010:0> if y <= x
irb(main):011:1> puts "y ist kleiner oder gleich x!"
irb(main):012:1> end
y ist kleiner oder gleich x!
=> nil
irb(main):013:0>

Vorsicht ist jedoch bei der Prüfung auf Gleichheit geboten: Der Operator = bewirkt nämlich nur und ausschließlich Zuweisungen. Zum Testen auf exakte Äquivalenz musst du den Operator == benutzen. Mithilfe deines bisherigen Wissens kannst du dann doch bestimmt erklären, warum die erste dieser zwei if-Bedingungen nicht ausgeführt wird?

1
2
3
4
5
6
7
8
9
10
11
12
irb(main):013:0> z = false
=> false
irb(main):014:0> if z = false
irb(main):015:1> puts "z ist false!"
irb(main):016:1> end
=> nil
irb(main):017:0> if z == false
irb(main):018:1> puts "z ist false!"
irb(main):019:1> end
z ist false!
=> nil
irb(main):020:0>

4. Fall: Und oder nicht?

Du kannst mehrere Bedingungen mit »und« sowie »oder« verknüpfen. Die Operatoren and, or und not (diesen solltest du schon kennen) machen genau das, was man von ihnen erwartet:

1
2
3
4
5
6
irb(main):001:0> if 2.even? and not 3.even?
irb(main):002:1> puts "2 ist gerade und 3 nicht."
irb(main):003:1> end
2 ist gerade und 3 nicht.
=> nil
irb(main):004:0>

Außerdem gibt es noch die Kurzformen && (und), || (oder) und ! (nicht; auch die kennst du schon). Sie gleichen den ausgeschrieben Wörtern in ihrer Bedeutung fast bis auf's Haar, aber eben nur fast. Für den Moment genügt es aber, sie als gleich anzusehen.

5. Fall: Und was, wenn nicht?

Du kannst Alternativmöglichkeiten angeben. Und zwar mithilfe der Schlüsselwörter elsif und else. Jeder if-Block kann beliebig viele elsif-Klauseln beinhalten, aber nur eine else-Klausel. Er wird dann von oben abgearbeitet, eine Bedingung nach der anderen, und sobald eine zutrifft, der dazugehörige Codeblock ausgeführt. Trifft keine zu, tritt der else zugewiesene Block in Aktion.

1
2
3
4
5
6
7
8
9
if dies_und_das
  #Code...
elsif das_und_das
  #Code...
elsif pruefe_dieses
  #Code...
else
  #Na gut, dann mach eben das hier.
end


Weitere Bedingungen

Für eine konkrete Fallunterscheidung einer bestimmten Variable ist zudem die case-Struktur praktisch. Sie ermöglicht es, ohne großen Tippaufwand viele verschiedene, aber ähnliche Fälle zu behandeln. Nehmen wir an, wir müssten verschiedenen Code ausführen, je nachdem, wie der Wert von x ist. Es wäre möglich dies langwierig mit if abzufragen:

1
2
3
4
5
6
7
8
9
10
11
if x == 1
  #Code...
elsif x == 2
  #Code...
elsif x == 3
  #Code...
elsif x == 4
  #Code...
else
  #Sonst was...
end

Kompakter mit case:

1
2
3
4
5
6
7
8
9
10
11
12
case x
  when 1
    #Code...
  when 2
    #Code...
  when 3
    #Code...
  when 4
    #Code...
  else
    #Code...
end

Ist die Anweisung zudem nur eine Zeile lang, wird es richtig praktisch:

1
2
3
4
5
6
7
8
case x
  when 1 then #Code...
  when 2 then #Code...
  when 3 then #Code...
  when 4 then #Code...
  else
    #Code...
end

case benutzt aber den Vergleichsoperator === anstatt von ==. Dies führt gelegentlich zu fragwürdigen Ergebnissen, ist aber in der Regel ungefährlich. Wir werden darauf zu sprechen kommen, wenn wir die Core-Klassen von Ruby behandeln.

Ternäroperator

Diese kleine Struktur wurde aus C übernommen. Sie ermöglicht es, kurzen if..else-Code kurz und bündig in eine Zeile zu schreiben:

meine_bedingung ? wenn_true_dann_das_hier : wenn_false_dann_das_hier

Angewandt:

1
2
x = 5
x < 10 ? puts "x kleiner 10!" : puts "x größer 10!"


^ Zurück zum Inhalt | ? Nächstes Kapitel