Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Geleitwort des Fachgutachters
Einleitung
1 Einführung
2 Installation
3 Erste Schritte
4 Einführung in Ruby
5 Eine einfache Bookmarkverwaltung
6 Test-Driven Development
7 Rails-Projekte erstellen
8 Templatesystem mit ActionView
9 Steuerzentrale mit ActionController
10 Datenbankzugriff mit ActiveRecord
11 E-Mails verwalten mit ActionMailer
12 Nützliche Helfer mit ActiveSupport
13 Ajax on Rails
14 RESTful Rails und Webservices
15 Rails mit Plug-ins erweitern
16 Performancesteigerung
17 Sicherheit
18 Veröffentlichen einer Rails-Applikation auf einem Server
Ihre Meinung?

Spacer
 <<   zurück
Ruby on Rails 2 von Hussein Morsy, Tanja Otto
Das Entwickler-Handbuch
Buch: Ruby on Rails 2

Ruby on Rails 2
geb., mit DVD
699 S., 39,90 Euro
Rheinwerk Computing
ISBN 978-3-89842-779-1
Online bestellenPrint-Version Jetzt Buch bestellen
* versandkostenfrei in (D) und (A)
Pfeil 4 Einführung in Ruby
  Pfeil 4.1 Was ist Ruby?
  Pfeil 4.2 Ruby-Code ausführen
  Pfeil 4.3 Grundlagen
  Pfeil 4.4 Zahlen
  Pfeil 4.5 Zeichenketten
  Pfeil 4.6 Symbole
  Pfeil 4.7 Reguläre Ausdrücke
  Pfeil 4.8 Arrays
  Pfeil 4.9 Hashes
  Pfeil 4.10 Datum und Zeit
  Pfeil 4.11 Module


Rheinwerk Computing - Zum Seitenanfang

4.9 Hashes  Zur nächsten ÜberschriftZur vorigen Überschrift

Assoziative Arrays

Hashes sind auch unter den Begriffen assoziative Arrays oder Dictionaries bekannt. Während ein Array nur einen ganzzahligen Index, zu dem ein Wert gespeichert werden kann, akzeptiert, akzeptiert ein Hash jeden Wert als Index. Beide Datenstrukturen haben Vor- und Nachteile. Bei einem Array können wir davon ausgehen, dass es eine geordnete Datenstruktur enthält. Wir können uns darauf verlassen, dass Element 4 ein Element 3 vorausgegangen ist. In einem Hash kann der Index ein Wert sein, der nicht wirklich einen Vorgänger oder Nachfolger hat. Ein Hash ist ein nützliches und leistungsfähiges Programmier-Instrument.


Rheinwerk Computing - Zum Seitenanfang

Einen Hash erzeugen  Zur nächsten ÜberschriftZur vorigen Überschrift

Auch zur Erzeugung eines Hashs steht wie für die Erzeugung eines Arrays die Klassen-Methode [] zur Verfügung. Als Äquivalent kann das Literal {} verwendet werden. Wir zeigen Ihnen hier sechs Möglichkeiten, einen Hash mit diesen Methoden zu erzeugen:

>> a1 = Hash.[]("Hemden",3,"Hosen",2)
=> {"Hemden"=>3, "Hosen"=>2}
>> a2 = Hash.[]("Hemden"=>3,"Hosen"=>2)
=> {"Hemden"=>3, "Hosen"=>2}
>> b1 = Hash["Hemden",3,"Hosen",2]
=> {"Hemden"=>3, "Hosen"=>2}
>> b2 = Hash["Hemden"=>3,"Hosen"=>2]
=> {"Hemden"=>3, "Hosen"=>2}
>> c1 = {"Hemden",3,"Hosen",2}
=> {"Hemden"=>3, "Hosen"=>2}
>> c2 = {"Hemden"=>3,"Hosen"=>2}
=> {"Hemden"=>3, "Hosen"=>2}

Wenn Sie, wie im ersten Beispiel gezeigt, einen Hash erzeugen, müssen Sie darauf achten, eine gerade Anzahl von Werten zu übergeben.

Standardwert

Sie können auch einen neuen Hash mit der Klassenmethode new erzeugen, der Sie einen optionalen Parameter als Standardwert übergeben können. Egal, ob Sie den Parameter übergeben oder nicht, es wird in jedem Fall ein leerer Hash erzeugt. Der Parameter setzt den Standardwert. Das heißt, wird ein Index des Hash aufgerufen, den es nicht gibt, wird dieser Standardwert statt nil ausgegeben:

>> e = Hash.new(99)
=> {}
>> e['b']
=> 99
>> f = Hash.new("a" => 3)
=> {}
>> f['c']
=> {"a"=>3}
>> g = Hash.new
=> {}
>> g['a']
=> nil

default

Der Standardwert eines Hash kann auch über die Methode default gesetzt oder überschrieben werden. Mit der Methode << kann der Standardwert erweitert werden:

>> a = Hash.new("Wert fehlt")
=> {}
>> a['name']
=> "Wert fehlt"
>> a.default = "fehlender Wert"
=> "fehlender Wert"
>> a['name']
=> "fehlender Wert"
>> a['nach'] << " name"
=> "fehlender Wert name"
>> a.default
=> "fehlender Wert name"

fetch

Die Methode fetch ist der Methode [] ähnlich, mit dem Unterschied, dass sie einen IndexError ausgibt, wenn der aufgerufene Index nicht existiert, es sei denn, Sie haben der Methode als zweiten Parameter einen Standardwert übergeben, der stattdessen ausgegeben wird. fetch können Sie auch einen Block übergeben, der dann ausgeführt wird, wenn es den angefragten Index nicht gibt. Dadurch kann für jeden fehlenden Index ein anderer Standardwert zurückgegeben werden:

>> a = {"Hemden",1,"Hosen",2,"T-Shirts",3}
=> {"T-Shirts"=>3, "Hemden"=>1, "Hosen"=>2}
>> a.fetch("Blusen")
IndexError: key not found
	from (irb):2:in 'fetch'
	from (irb):2
	from :0
>> a.fetch("Hosen","na")
=> 2
>> a.fetch("Blusen","na")
=> "na"
>> a.fetch("Hemden") {|x| x.upcase}
=> 1
>> a.fetch("Blusen") {|x| x.upcase}
=> "BLUSEN"

Alle fehlenden Indizes verweisen auf den gleichen Standardwert. Das heißt, wird der Standardwert geändert, ändert er sich für alle fehlenden Indizes.


Rheinwerk Computing - Zum Seitenanfang

Zugriff auf Elemente eines Hashs  Zur nächsten ÜberschriftZur vorigen Überschrift

Hashes haben auch die Klassenmethoden [] und []=, die so verwendet werden wie bei Arrays, außer dass der Methode [] nur ein Parameter für den Index und der Methode []= nur zwei Parameter für den Index und den Wert übergeben werden dürfen. Der Parameter für den Index kann von jedem Typ sein, nicht nur vom Typ String, wenn auch meistens Strings verwendet werden. Die Methode store ist ein Alias der Methode []=:

>> a = {}
=> {}
>> a["Hemden"] = 3
=> 3
>> a.[]=("Hosen",2)
=> 2
>> a.store("Blusen",5)
=> 5
>> a
=> {"Hemden"=>3, "Blusen"=>5, "Hosen"=>2}
>> a.[]("Hosen")
=> 2

Ist Hash definiert?

Wenn wir nicht sicher sind, ob ein Hash existiert, und wir es vermeiden wollen, einen existierenden Hash zu löschen, können wir das Problem mit folgender Abfrage lösen:

unless defined? a
a={}
end
a["Hemden"] = 3

Kürzer können Sie das auch so schreiben:

a ||= {}
a["Hemden"] = 3

oder so:

(a ||= {})["Hemden"] = 3

Diese Abfrage können Sie auch auf Indizes anwenden, wenn Sie zum Beispiel nur dann einen Wert zuweisen wollen, wenn kein Wert gesetzt ist:

>> a = Hash.new(99)
=> {}
>> a[2]
=> 99
>> a[2] ||= 5
=> 99
>> a
=> {}
>> b = Hash.new
=> {}
>> b[2]
=> nil
>> b[2] ||=5
=> 5
>> b
=> {2=>5}

Der Wert nil kann in einem Hash sowohl als Index als auch als Wert gesetzt werden:

>> b = {}
=> {}
>> b[1]
=> nil
>> b[2] = nil
=> nil
>> b
=> {2=>nil}
>> b[2].nil?
=> true
>> b[3].nil?
=> true
>> b[nil] = 7
=> 7
>> b
=> {nil=>7, 2=>nil}

Rheinwerk Computing - Zum Seitenanfang

Schlüssel-Wert-Paare löschen  Zur nächsten ÜberschriftZur vorigen Überschrift

Die Schlüssel-Wert-Paare eines Hash können Sie mit Hilfe der Methoden clear, delete, delete_if, reject, reject! und shift löschen.

clear

Mit der Methode clear leeren Sie den gesamten Hash. Das ist das Gleiche, wie den Hash mit einem leeren Hash zu überschreiben, aber etwas schneller.

shift

Die Methode shift löscht ein zufälliges Schlüssel-Wert-Paar. Sie liefert das gelöschte Paar als Array mit zwei Werten zurück oder nil, wenn keine Werte entfernt wurden:

>> a = {1=>2, 3=>4}
=> {1=>2, 3=>4}
>> b = a.shift
=> [1, 2]
>> a
=> {3=>4}

delete

Mit der Methode delete können Sie ein bestimmtes Schlüssel-Wert-Paar entfernen. Die Methode erwartet den Schlüssel als Parameter und liefert den Wert zurück, wenn der Schlüssel vorhanden war. Wenn nicht, liefert sie den Standardwert zurück. Sie können auch zusätzlich einen Block übergeben, um den Standardwert festzulegen:

>> a = {1=>1, 2=>4, 3=>9, 4=>16}
=> {1=>1, 2=>4, 3=>9, 4=>16}
>> a.delete(3)
=> 9
>> a.delete(5)
=> nil
>> a.delete(6) {"nicht gefunden"}
=> "nicht gefunden"

delete_if, reject

Die Methoden delete_if, reject und reject! erwarten einen Block und löschen alle Schlüssel, für die der Block true zurückliefert:

>>  h = { "a" => 100, "b" => 200, "c" => 300 }
=> {"a"=>100, "b"=>200, "c"=>300}
>>  h.delete_if {|key, Wert| Wert > 200 }
=> {"a"=>100, "b"=>200}
>> h.reject {|key, Wert| Wert > 100 }
=> {"a"=>100}
>> h
=> {"a"=>100, "b"=>200}
>> h.reject! {|key, Wert| Wert > 100 }
=> {"a"=>100}
>> h
=> {"a"=>100}

Rheinwerk Computing - Zum Seitenanfang

Über einen Hash iterieren  Zur nächsten ÜberschriftZur vorigen Überschrift

Neben dem Standarditerator each stellt die Klasse Hash die Iteratoren each_key, each_value und each_pair zur Verfügung, wobei each_pair ein Alias für each ist. Allen Iteratoren können Sie einen Block übergeben. each und each_pair übergeben sowohl den Schlüssel als auch den Wert an den Block. Die anderen beiden übergeben ihrem Namen entsprechend entweder nur den Schlüssel oder nur den Wert in den Block:

{"a"=>3,"b"=>2}.each do |key, val|
  print val, " von ", key, "; "
end
# 3 von a; 2 von b;

{"a"=>3,"b"=>2}.each_key do |key|
  print "key = #{key};"
end
# key = a; key = b;

{"a"=>3,"b"=>2}.each_value do |value|
  print "val = #{value};"
end
# val = 3; val = 2;

Rheinwerk Computing - Zum Seitenanfang

Schlüssel und Wert in einem Hash vertauschen  Zur nächsten ÜberschriftZur vorigen Überschrift

invert

Dank der Methode invert ist das Vertauschen von Schlüssel und Wert in einem Hash eigentlich ganz einfach. Das einzige Problem, das auftreten kann, ist, dass in einem Hash die Schlüssel eindeutig sein müssen. Das heißt, sollte es vor dem Vertauschen den gleichen Wert mehrmals zu unterschiedlichen Schlüsseln gegeben haben, wird es hinterher nur ein neues Schlüssel-Wert-Paar geben. Darauf, welches Paar das sein wird, hat man leider keinen Einfluss:

>> a = {"manon"=>4711, "pinho"=>4712,
		    "joelle"=>4713, "chris"=>4714}
=> {"chris"=>4714, "joelle"=>4713, "pinho"=>4712,
   "manon"=>4711}
>> b = a.invert
=> {4713=>"joelle", 4714=>"chris", 4711=>"manon",
   4712=>"pinho"}
>> b[4711]
=> "manon"

Rheinwerk Computing - Zum Seitenanfang

Schlüssel und Werte in einem Hash finden  Zur nächsten ÜberschriftZur vorigen Überschrift

has_key?, include?, key?, member?

Ob ein bestimmter Schlüssel in einem Hash enthalten ist, können Sie mit Hilfe der Methode has_key? oder mit einem ihrer Aliasse include?, key? oder member? herausfinden:

>> a = {"a"=>1,"b"=>2}
=> {"a"=>1, "b"=>2}
>> a.has_key? "c"
=> false
>> a.include? "a"
=> true
>> a.key? 1
=> false
>> a.member? "b"
=> true

empty?

Mit der Methode empty? können Sie ermitteln, ob ein Hash leer ist oder nicht:

>> a.empty?
=> false

length, size

Die Methode length oder ihr Alias size liefern die Anzahl der Elemente eines Hash zurück. Ist der Hash leer, ist der Rückgabewert 0:

>> a.length
=> 2

has_value?, value?

Ob ein bestimmter Wert in einem Hash enthalten ist, können Sie mit den Methoden has_value? oder value? abfragen:

>> a.has_value? 2
=> true
>> a.value? 5
=> false

Rheinwerk Computing - Zum Seitenanfang

Einen Hash in ein Array extrahieren  Zur nächsten ÜberschriftZur vorigen Überschrift

to_a

Um ganze Hashes in ein Array zu extrahieren, steht die Methode to_a zur Verfügung. Das Ergebnis-Array enthält die Schlüssel-Wert-Paare als Arrays:

>>  h = {"a"=>1,"b"=>2}
=> {"a"=>1, "b"=>2}
>> b = h.to_a
=> [["a", 1], ["b", 2]]
>> b.first
=> ["a", 1]

keys, values

Sie können auch nur die Schlüssel oder nur die Werte eines Hash als Array extrahieren. Dazu dienen die Methoden keys und values:

>> h.keys
=> ["a", "b"]
>> h.values
=> [1, 2]

values_at

Mit der Methode values_at können Sie auch nur bestimmte Werte eines Hash in ein Array extrahieren:

>> h = {1=>"un", 2=>"deux", 3=>"trois",
"four"=>"quatre"}
=> {1=>"un", 2=>"deux", 3=>"trois", "four"=>"quatre"}
>> h.values_at(2,"four",3)
=> ["deux", "quatre", "trois"]
>> h.values_at(1,3)
=> ["un", "trois"]

Rheinwerk Computing - Zum Seitenanfang

Nach Schlüssel-Wert-Paaren suchen  Zur nächsten ÜberschriftZur vorigen Überschrift

Da die Klasse Hash das Modul Enumerable inkludiert, können Sie die Methoden detect (find), select (find_all), grep, min, max und reject genauso anwenden wie auf ein Array.

detect, find

Die Methode detect (Alias: find) erwartet einen Block, dem die Schlüssel-Wert-Paare einzeln übergeben werden. Als Ergebnis wird das erste Schlüssel-Wert-Paar zurückgeliefert, für das der Block true liefert:

>> namen = {"chris" => "internet",
"joelle" => "grafik", "pinho" => "grafik"}
=> {"chris"=>"internet", "joelle"=>"grafik",
    "pinho"=>"grafik"}
>> puts namen.detect {|k,v| v == "grafik"}
joelle
grafik

Selbstverständlich können sowohl die Objekte in einem Hash als auch der Block von größerer Komplexität sein. Das Einzige, was Probleme bereitet, ist das Vergleichen von unterschiedlichen Typen.

select, find_all

Die Methode select (Alias: find_all) liefert alle Schlüssel-Wert-Paare, für die der ihr übergebene Block true liefert, als Ergebnis zurück:

>> puts namen.select {|k,v| v == "grafik"}
joelle
grafik
pinho
grafik

Rheinwerk Computing - Zum Seitenanfang

Einen Hash sortieren  Zur nächsten ÜberschriftZur vorigen Überschrift

Sortiertes Array

Hashes sind von Natur aus unsortiert. Um einen Hash trotzdem sortieren zu können, wandelt Ruby den Hash in ein Array um und sortiert es. Als Ergebnis wird ein sortiertes Array zurückgeliefert.

>> namen = {"Darth" => "Vader",
"Obi-Wan" => "Kenobi", "Anakin" => "Skywalker"}
=> {"Darth"=>"Vader", "Obi-Wan"=>"Kenobi",
    "Anakin"=>"Skywalker"}
>> namen.sort
=> [["Anakin", "Skywalker"], ["Darth", "Vader"],
    ["Obi-Wan", "Kenobi"]]

Rheinwerk Computing - Zum Seitenanfang

Zwei Hashes miteinander mischen  Zur nächsten ÜberschriftZur vorigen Überschrift

merge, update

Die Methode merge (Alias: update) mischt die Einträge zweier Hashes miteinander. Es wird ein dritter Hash gebildet, in dem alle Duplikate überschrieben werden:

>> h1 = {"Ruby" => "Edelstein", "PHP" => "Programmiersprache"}
=> {"PHP"=>"Programmiersprache", "Ruby"=>"Edelstein"}
>> h2 = {"Java" => "Programmiersprache",
"Ruby" => "Programmiersprache"}
=> {"Ruby"=>"Programmiersprache","Java"=>"Programmiersprache"}
>> h3 = h1.merge(h2)
=> {"PHP"=>"Programmiersprache", "Ruby"=>"Programmiersprache",
"Java"=>"Programmiersprache"}

Sie können auch einen Block übergeben, der eine Logik enthält, um zu entscheiden, welcher der doppelten Schlüssel in den neuen Hash übernommen wird. In unserem Beispiel definieren wir einen Block, der im Falle von zwei gleichen Schlüsselwerten das Schlüssel-Wert-Paar mit dem kleineren Wert (alphabetisch oder numerisch) übernimmt:

>> h4 = h1.merge(h2) {
|key,old,new| old < new ? old : new }
=> {"PHP"=>"Programmiersprache", "Ruby"=>"Edelstein",
   "Java"=>"Programmiersprache"}

Es stehen auch die Methoden merge! und update! zur Verfügung, die das Ausgangsobjekt ändern.


Rheinwerk Computing - Zum Seitenanfang

Einen Hash aus einem Array erzeugen  topZur vorigen Überschrift

Sie können ganz einfach aus einem Array einen Hash erzeugen, indem Sie das Array der Klasse Hash in der Methode [] übergeben. Sie müssen nur darauf achten, dass das Array eine gerade Anzahl von Elementen enthält:

>> array = [2, 3, 4, 5, 6, 7]
=> [2, 3, 4, 5, 6, 7]
>> hash = Hash[*array]
=> {6=>7, 2=>3, 4=>5}


Ihre Meinung

Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.

 <<   zurück
  Zum Rheinwerk-Shop
Zum Rheinwerk-Shop: Ruby on Rails 2
Ruby on Rails 2
Jetzt Buch bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: Ruby on Rails 3.1






 Ruby on Rails 3.1


Zum Rheinwerk-Shop: Responsive Webdesign






 Responsive Webdesign


Zum Rheinwerk-Shop: Suchmaschinen-Optimierung






 Suchmaschinen-
 Optimierung


Zum Rheinwerk-Shop: JavaScript






 JavaScript


Zum Rheinwerk-Shop: Schrödinger lernt HTML5, CSS3 und JavaScript






 Schrödinger lernt
 HTML5, CSS3
 und JavaScript


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag GmbH, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern