Die Programmiersprache Ruby (German Edition)
Informationen über die API, die die Klasse
Hash
definiert, werden in „9.5.3 Hashes“ zur Verfügung gestellt.
3.4.1 Hash-Literale
Ein Hash-Literal wird als eine durch kommaseparierte Liste von Schlüssel/Wert-Paaren geschrieben, umschlossen von geschweiften Klammern. Schlüssel und Werte werden durch einen »Zwei-Zeichen-Pfeil« voneinander getrennt:
=>
. Das oben erzeugte
Hash
-Objekt könnte auch durch folgendes Literal erzeugt werden:
numbers = { "eins" => 1, "zwei" => 2, "drei" => 3 }
In der Regel funktionieren
Symbol
-Objekte als Hash-Schlüssel effizienter als Strings:
numbers = { :eins => 1, :zwei => 2, :drei => 3 }
Symbole sind unveränderliche, interne Strings, die als Bezeichner mit führendem Doppelpunkt geschrieben werden; sie werden in „3.6 Symbole“ weiter unten in diesem Kapitel erläutert.
Ruby 1.8 erlaubt Kommata anstelle von Pfeilen, aber in Ruby 1.9 wird diese veraltete Syntax nicht mehr unterstützt:
numbers = { :eins, 1, :zwei, 2, # Dasselbe, aber schlechter lesbar
Sowohl Ruby 1.8 als auch Ruby 1.9 erlauben ein einzelnes schließendes Komma am Ende der Schlüssel/Wert-Liste:
numbers = { :eins => 1, :zwei => 2, } # Abschließendes Komma ignoriert
Ruby 1.9 unterstützt eine sehr praktische und kompakte Hash-Literal-Syntax, wenn die Schlüssel Symbole sind. In diesem Fall wandert der Doppelpunkt an das Ende des Hash-Schlüssels und ersetzt den Pfeil: [ 9 ]
numbers = { eins: 1, zwei: 2, drei: 3 }
Beachten Sie, dass zwischen dem Hash-Schlüssel-Bezeichner und dem Doppelpunkt kein Leerzeichen stehen darf.
3.4.2 Hash-Codes, Gleichheit und veränderliche Schlüssel
Ruby-Hashes werden, wenig überraschend, durch eine Datenstruktur implementiert, die als Hash-Tabelle (englisch hash table ) bekannt ist. Objekte, die als Schlüssel in einem Hash verwendet werden, müssen eine Methode namens
hash
besitzen, die einen
Fixnum
- Hash-Code für den Schlüssel zurückliefert. Wenn zwei Schlüssel identisch sind, müssen sie denselben Hash-Code haben. Auch ungleiche Schlüssel können denselben Hash-Code haben, aber Hash-Tabellen sind am effizientesten, wenn doppelte Hash-Codes selten vorkommen.
Die Klasse
Hash
überprüft Schlüssel mit der Methode
eql?
auf Gleichheit. Bei den meisten Ruby-Klassen funktioniert
eql?
wie der Operator
==
(siehe „3.8.5 Objektgleichheit“ für Details). Wenn Sie eine neue Klasse definieren, die die Methode
eql?
überschreibt, müssen Sie auch die Methode
hash
überschreiben, denn ansonsten funktionieren Instanzen Ihrer Klasse nicht als Schlüssel in einem Hash. (Beispiele, wie man eine
hash
-Methode schreibt, sehen wir in Kapitel 7 .)
Wenn Sie eine Klasse definieren und
eql?
nicht überschreiben, werden Instanzen dieser Klasse beim Einsatz als Hash-Schlüssel auf Objektidentität geprüft. Zwei verschiedene Instanzen Ihrer Klasse sind selbst dann verschiedene Hash-Schlüssel, wenn sie denselben Inhalt repräsentieren. In diesem Fall liegt das an der Standardmethode
hash
: Sie gibt die eindeutige
object_id
des Objekts zurück.
Beachten Sie, dass veränderliche Objekte als Hash-Schlüssel problematisch sind. Eine Änderung des Inhalts eines Objekts ändert normalerweise seinen Hash-Code. Wenn Sie ein Objekt als Schlüssel verwenden und dieses Objekt dann ändern, gerät die interne Hash-Tabelle durcheinander, und der Hash funktioniert nicht mehr richtig.
Da Strings veränderlich, aber häufig genutzte Hash-Schlüssel sind, behandelt Ruby sie als Sonderfall und erstellt private Kopien aller Strings, die als Schlüssel verwendet werden. Dies ist jedoch der einzige Sonderfall; Sie müssen sehr vorsichtig sein, wenn Sie andere veränderliche Objekte als Hash-Schlüssel verwenden. Ziehen Sie in Betracht, eine private Kopie zu erstellen oder die Methode
freeze
aufzurufen. Wenn Sie veränderliche Hash-Schlüssel einsetzen müssen, rufen Sie bei jeder Änderung eines Schlüssels die Methode
rehash
des
Hash
-Objekts auf.
3.5 Bereiche
Ein
Range
-Objekt oder Bereich repräsentiert die Werte zwischen einem Start- und einem Endwert. Bereichsliterale werden geschrieben, indem man zwei oder drei Punkte zwischen dem Start- und dem Endwert platziert. Werden zwei Punkte verwendet, dann ist der Bereich inklusiv , und der Endwert ist Teil des Bereichs. Wenn drei Punkte zum Einsatz kommen, dann ist der Bereich exklusiv , und der Endwert ist kein Teil des Bereichs:
1..10 # Die Integer 1 bis 10 einschließlich 10
1.0...10.0 # Die Zahlen zwischen 1.0 und 10.0, 10.0 selbst
Weitere Kostenlose Bücher