Die Programmiersprache Ruby (German Edition)
etwa
Math.sqrt
, sind idempotent: Sie können ohne Nebeneffekte aufgerufen werden. Andere Methoden sind nicht idempotent, und dies hängt stark davon ab, ob diese Methoden Wertzuweisungen an nicht lokale Variablen vornehmen.
----
4.5.1 Wertzuweisung an Variablen
Wenn man an Wertzuweisung denkt, denkt man in der Regel an Variablen, und in der Tat sind sie die häufigsten Lvalues in Zuweisungsausdrücken. Denken Sie daran, dass Ruby vier Arten von Variablen besitzt: lokale Variablen, globale Variablen, Instanzvariablen und Klassenvariablen. Sie werden durch das erste Zeichen im Variablennamen voneinander unterschieden. Die Wertzuweisung funktioniert für alle vier Variablenarten gleich, so dass Sie hier nicht zwischen den Variablenarten zu unterscheiden brauchen.
Behalten Sie im Kopf, dass die Instanzvariablen von Ruby-Objekten außerhalb des Objekts niemals sichtbar sind, und dass Variablennamen niemals durch einen Objektnamen qualifiziert werden. Betrachten Sie diese Wertzuweisung:
point.x, point.y = 1, 2
Die Lvalues in diesem Ausdruck sind keine Variablen; es sind Attribute, die in Kürze erläutert werden.
Wertzuweisung an eine Variable funktioniert so, wie Sie es erwarten würden: Die Variable wird einfach auf den angegebenen Wert gesetzt. Der einzige Knackpunkt hat mit Variablendeklaration und mit der mangelnden Eindeutigkeit der Unterscheidung zwischen lokalen Variablennamen und Methodennamen zu tun. Ruby hat keine Syntax zur expliziten Deklaration einer Variablen: Variablen entstehen einfach, wenn ihnen ein Wert zugewiesen wird. Außerdem sehen die Namen von lokalen Variablen und Methoden gleich aus – es gibt kein Präfix wie
$
, das sie unterscheidet. Deshalb könnte ein einfacher Ausdruck wie
x
sich sowohl auf eine lokale Variable namens
x
als auch auf eine Methode von
self
namens
x
beziehen. Um diese Doppeldeutigkeit aufzulösen, behandelt Ruby einen Bezeichner als lokale Variable, wenn irgendwann vorher eine Wertzuweisung an die Variable angetroffen wurde. Das geschieht selbst dann, wenn diese Wertzuweisung niemals ausgeführt wird. Der folgende Code demonstriert dies:
class Ambiguous
def x; 1; end # Eine Methode namens "x". Gibt immer 1 zurück.
def test
puts x # Keine Variable gefunden; gilt für obige Methode: Gibt 1 aus.
# Die Zeile unten wird wegen "if false" nie ausgeführt. Aber
# Der Parser sieht sie und behandlet für den Rest der Methode x als Variable.
x = 0 if false
puts x # x ist eine Variable, erhielt aber nie einen Wert: Gibt nil aus.
x = 2 # Diese Wertzuweisung wird ausgewertet.
puts x # Deshalb gibt diese Zeile nun 2 aus.
end
end
4.5.2 Wertzuweisung an Konstanten
Konstanten unterscheiden sich in einem offensichtlichen Punkt von Variablen: Ihre Werte sollen während der gesamten Ausführung eines Programms konstant bleiben. Deshalb gelten für die Wertzuweisung an Konstanten einige spezielle Regeln:
Wertzuweisung an eine Konstante, die bereits existiert, sorgt dafür, dass Ruby eine Warnung ausgibt. Ruby führt die Wertzuweisung aber trotzdem aus, was bedeutet, dass Konstanten nicht wirklich konstant sind.
Innerhalb des Rumpfes einer Methode ist Wertzuweisung an Konstanten nicht erlaubt. Ruby geht davon aus, dass Methoden dafür gedacht sind, mehr als einmal aufgerufen zu werden; wenn Sie einer Konstante in einer Methode einen Wert zuweisen könnten, würde diese Methode bei jedem weiteren Aufruf nach dem ersten eine Warnung ausgeben. Deshalb ist es einfach nicht erlaubt.
Anders als Variablen entstehen Konstanten nicht, solange der Ruby-Interpreter den Wertzuweisungsausdruck nicht tatsächlich ausführt. Ein nicht ausgewerteter Ausdruck wie der folgende erzeugt keine Konstante:
N = 100 if false
Beachten Sie, dass dies bedeutet, dass sich eine Konstante nie in einem uninitialisierten Zustand befindet. Wenn eine Konstante existiert, wurde ihr auch ein Wert zugewiesen. Eine Konstante hat nur dann den Wert
nil
, wenn das tatsächlich der Wert ist, der ihr zugewiesen wurde.
4.5.3 Wertzuweisung an Attribute und Array-Elemente
Wertzuweisung an ein Attribut oder ein Array-Element ist in Wirklichkeit die Ruby-Kurzschreibweise für einen Methodenaufruf. Angenommen, ein Objekt
o
hat eine Methode namens
m=
, wobei das letzte Zeichen des Methodennamens ist ein Gleichheitszeichen. Dann kann
o.m
als Lvalue in einem Wertzuweisungsausdrucks verwendet werden. Nehmen wir weiterhin an, dass der Wert
v
zugewiesen wird:
o.m = v
Der Ruby-Interpreter konvertiert diese Wertzuweisung in den
Weitere Kostenlose Bücher