Galileo Computing < openbook > Galileo 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

Download:
- ZIP, ca. 6,7 MB
Buch bestellen
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
Galileo Computing
ISBN 978-3-89842-779-1
Online bestellenPrint-Version jetzt 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


Galileo 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.


Galileo 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.


Galileo 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}

Galileo 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}

Galileo 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;

Galileo 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"

Galileo 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

Galileo 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"]

Galileo 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

Galileo 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"]]

Galileo 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.


Galileo 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}


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  Zum Katalog
Zum Katalog: Ruby on Rails 2






Ruby on Rails 2
Jetzt bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Zend Framework






 Zend Framework


Zum Katalog: AJAX






 AJAX


Zum Katalog: Praxisbuch Web 2.0






 Praxisbuch Web 2.0


Zum Katalog: CSS-Layouts






 CSS-Layouts


Zum Katalog: JavaScript und Ajax






 JavaScript und Ajax


Zum Katalog: Professionelles Webdesign mit (X)HTML und CSS






 Professionelles Webdesign
 mit (X)HTML und CSS


Zum Katalog: Suchmaschinen-Optimierung






 Suchmaschinen-Optimierung


Zum Katalog: XHTML, HTML und CSS






 XHTML, HTML und CSS


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 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.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de