Die Programmiersprache Ruby

Blog| Forum| Wiki  

Sie ist eine für die Programmierung unentbehrlich wichtige Struktur und (fast) so alt wie die Programmierung selbst: Die Bedingung. So gut wie jede Programmiersprache unterstützt Bedingungen, die mit dem Schlüsselwort if eingeleitet werden, in einer ähnlichen Syntax. Neben dieser bekannten Bedingungsabfrage gibt es noch einige andere, weniger bekannte, aber deshalb nicht weniger nützliche Arten den Wahrheitswert einer Bedingung abzufragen.

Inhaltsverzeichnis

if

Die bekannteste Bedingung, deren Syntax in fast jeder Programmiersprache nahezu gleich ist. In Ruby kann man sowohl die Klammern um die Bedingung, als auch ein then hinter der Zeile (außer die Bedingung ist ein Einzeiler) weglassen. Wichtig dabei ist auch, dass Vergleiche in Ruby mit der Methode == und nicht mit der Zuweisung = durchgeführt werden. if not kann als unless geschrieben werden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
a = true
if a == true
  puts "a war true!"
end
#=> a war true!
# Wenn nur auf true ��berpr��ft wird, kann man das auch so schreiben: 
if a
  puts "a war true!"
end
#=> a war true!

#Jedes Objekt gilt in Ruby als true (au��er false und nil)
a = 7
b = "T"
if a
  puts "true"
end
if b
  puts "true"
end
#=> true
#=> true

#Vorsicht!
if 0
  puts "true"
end
#=> true

#F��r if not a kann man auch unless benutzen: 
a = false
unless a
  puts "false"
end
#=> false
#--------------------------------------------------------------
a = true
if a then puts "a war true!" end
#=> a war true!

Wie in vielen anderen Programmiersprachen, kennt Ruby auch die else-if und die else-Klausel, wobei else-if in Ruby zu elsif zusammengekürzt wird.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
a, b = true, false
#a = true; b = false
if b
  puts "b war true!"
elsif a
  puts "a war true!"
end
#=> a war true!

a, b, c = false, false, false
if a
  puts "a war true!"
elsif b
  puts "b war true!"
elsif c
  puts "c war true!"
else
  puts "Weder a noch b war true!"
end
#=> Weder a noch b war true!


case

Für lange, geschachtelte Bedinungsabfragen, die sonst viele elsif-Teile benötigten, bietet sich das case-Konstrukt an. Es hat eine Besonderheit: Es führt die Vergleiche intern nicht mit der Methode ==, sondern mit der Methode === aus[1] (um Fragen vorzubeugen: Nein, eine Methode ==== gibt es nicht), das ist wichtig, wenn zum Beispiel Dinge verglichen werden, bei denen es eigentlich nicht um das Objekt selbst, sondern um etwas anderes geht. Die Variable, die man case mitgibt, kann gleichzeitig auf viele Werte überprüft werden:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
a = 3
case a
  when 1
    puts "a war 1"
  when 2
    puts "a war 2"
  when 3
    puts "a war 3"
  else # <== Auch ein Case-Konstrukt kann eine else-M��glichkeit haben!
    puts "a war weder 1 noch 2 noch 3. "
end
#=> a war 3
b = 2
case b
  when 1 then puts "b war 1"
  when 2 then puts "b war 2"
end
#=> b war 2
c = 1
case c
  when 1;puts "c war 1"
  when 2;puts "c war 2"
end
#=> c war 1
d = 0
case d
  when 1 : puts "d war 1"
  when 0 : puts "d war 0"
end
#=> d war 0

#Um den Unterschied zwischen == und === zu verdeutlichen: 
a = 1..10 #Range mit den Werten von 1 bis einschlie��lich 10
b = 5
a == b #=> false
a === b #=> true, denn 5 ist in 1-10 enthalten. 
#Ausformuliert hei��t das: 
if a == b
  #Das hier wird nicht ausgef��hrt. 
end
c = 1..4
case b # <== Aufpassen, b wird ��berpr��ft, nicht a!
  when a #Man kann die Bedingung so formulieren: Wenn b in a enthalten ist...
    #Das hier wird ausgef��hrt!
  when c #Wenn b in c enthalten ist...
    #Das hier wird nicht ausgef��hrt!
end

?

Eine sehr kurze Möglichkeit bietet der Ternäroperator ?:. Ruby hat ihn aus C übernommen, seine Syntax ist:
Bedingung ? Wenn-true-mache-das-hier : Sonst-mache-das-hier
.
1
2
3
a = 1
a == 4 ? puts("a war 4") : puts("a war nicht 4.")
#=> a war nicht 4.

Rückgabewerte

Was an Bedingungen überraschend sein kann, ist, dass sie Rückgabewerte haben, und zwar nicht nur true oder false. Eine Bedingungsabfrage gibt wie eine Methode immer den zuletzt "genannten" Wert zurück:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
a = 1
b = if a == 1
  9
else
  7
end
puts b #=> 9
#Ruby ignoriert beim Parsen des Codes den Whitespace, deswegen kann man sich das Case-Konstrukt
#getrost ��bersichtlich zurechtschieben. 
c = case a
      when 1
        "a = 1"
      when 2
        "a = 2"
      else
        "a weder 1 noch 2"
    end
puts c #=> a = 1
#Meistens benutzt man in solchen F��llen wohl den Tern��roperator: 
d = a == 2 ? "a war 2" : "a war nicht 2"
puts d #=> a war nicht 2

Das kann durchaus zu seltsamen Konstruktionen führen:

1
2
3
4
5
6
7
8
9
10
11
a = 9
b = case a
      when 8 then "a war 8" end
      when 9 then "a war 9" end
    end if a < 10
#Das hei��t nichts anderes, als: 
# 1. a wird der Wert 9 zugewiesen. 
# 2. Es wird ��berpr��ft, ob a kleiner 10 ist, 
# 3. Wenn ja, wird a genauer ��berpr��ft und (Wenn nein, ist hier Ende und b kriegt nix)
# 4. b wird das Ergebnis dieser ��berpr��fung zugewiesen. 
puts b #=> "a war 9"

||and or not!&&

Bedingungen können mit den Schlüsselwörtern and, or und not oder mit ihren Kurzformen &&, || und ! verknüpft werden, wobei die Kurzformen eine höhere Priorität aufweisen:

1
2
3
4
5
6
7
8
9
10
11
12
a, b, c = true, 7, false
if a and b == 7 and !c
  #Das hier wird ausgef��hrt
end
#In diesem Falle sind die Kurzformen gleich: 
if a && b == 7 && !c
  #Das hier wird auch ausgef��hrt
end
#Hier nicht: 
if a && b == 7 and !c
#Entspricht n��mlich: 
if (a and b == 7) and (not c)

Daneben gibt es noch &, | und ^, aber das sind keine Bedingungsoperatoren, sondern binäre:

1
2
3
1 & 0 #=> 0 (AND)
1 | 0 #=> 1 (OR)
1 ^ 0 #=> 1 (XOR)

Fußnoten

  1. case benutzt === aber nicht so, wie es in der Regel erwartet wird, sondern ruft die Methode === des zweiten Objekts anstatt des Ersten auf:

1
2
3
4
5
6
7
8
9
10
11
12
13
a = 1
b = 2
case a
  when b then puts "Gleich."
end
#Die Fallunterscheidung nutzt dabei diese Bedingungsabfrage: 
b === a
#und nicht
a === b
#Als Methode geschrieben wird der Unterschied deutlich: 
b.===(a)
#statt
a.===(b)

Siehe auch