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 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.3 Grundlagen  Zur nächsten ÜberschriftZur vorigen Überschrift

Semikolon nicht nötig

Ruby ist eine zeilenorientierte Sprache, das heißt, eine Anweisung endet am Ende einer Zeile. Daher ist ein Semikolon am Ende der Anweisung, wie z. B. in PHP oder Java, nicht notwendig.

Das Semikolon könnte eingesetzt werden, um mehrere Anweisungen in einer Zeile auszuführen. Das kann aber schnell unübersichtlich werden und ist deshalb nicht zu empfehlen.

Beispiel:

irb(main):001:0> preis = 12
=> 12
irb(main):002:0> mwst = 0.19
=> 0.19
irb(main):003:0> gesamt = preis * (1+mwst)
=> 14.28
irb(main):004:0> puts gesamt
14.28
=> nil
irb(main):005:0> print gesamt
14.28=> nil

Ausgaben mit puts und print

Ausgaben werden mit der Anweisung puts oder print ausgeführt. Der Unterschied besteht darin, dass puts nach der Ausgabe eine automatische Zeilenumschaltung ausführt und print nicht.

Hinweis
Die Ausgabe nil steht für ein leeres Objekt, das ausgegeben wird, weil puts eine Methode ist, die keinen Rückgabewert liefert.

Doch zunächst zur Syntax und zu Konventionen für Variablen, Konstanten und Methoden. Das Wichtigste zuerst:

Groß-/ Kleinschreibung

Ruby unterscheidet zwischen Groß- und Kleinschreibung bei Bezeichnungen von Variablen, das heißt, »mwst« ist etwas anderes als »Mwst«. Dabei ist man als Programmierer nicht frei bei der Wahl, ob man einen Bezeichner groß- oder kleinschreibt. Variablen- und Methodennamen werden immer kleingeschrieben. Besteht ein Variablenname aus mehreren Wörtern, werden diese durch Unterstriche voneinander getrennt, wobei jedes Wort kleingeschrieben wird (»snake_case«): neuer_preis = 14.28 . Klassennamen beginnen immer mit einem Großbuchstaben. Sollte der Name einer Klasse aus mehreren Wörtern bestehen, werden sie aneinandergeschrieben, wobei jedes Wort mit einem Großbuchstaben beginnt (»CamelCase«): PreisBerechnen . Konstantennamen werden komplett in Großbuchstaben geschrieben: MWST = 0.19


Rheinwerk Computing - Zum Seitenanfang

Variablen  Zur nächsten ÜberschriftZur vorigen Überschrift

In Ruby gibt es verschiedeneArten von Variablen, wie lokale Variablen, globale Variablen, Instanzvariablen und Klassenvariablen. Die Schreibweise der Variablen bestimmt die Art.

Lokale Variablen

Lokale Variablen werden innerhalb einer Methode oder eines anderen Programmblocks verwendet und sind nur innerhalb dieses Blocks gültig, das heißt, außerhalb dieses Blocks kann nicht auf diese Variablen zugegriffen werden. Sie beginnen mit einem Buchstaben oder einem Unterstrich.

Globale Variablen

Globale Variablen sind im ganzen Skript gültig, das heißt, man hat vom ganzen Skript aus Zugriff auf diese Variablen. Sie beginnen mit einem $-Zeichen.

Instanzvariablen

Instanzvariablen sind Attribute von Objekten, das heißt, es kann nur von dem besitzenden Objekt auf diese Variablen zugegriffen werden. Sie beginnen mit einem @ -Zeichen.

Klassenvariablen

Klassenvariablen gehören zur Klasse, das heißt, alle Instanzen der Klasse teilen sich diese Variablen. Sie beginnen mit zwei @ -Zeichen.

Für die Arbeit mit Ruby on Rails sind die lokalen Variablen und die Instanzvariablen am wichtigsten.

preis = 99 # lokale Variable
produkt = "Zahnbürste" # lokale Variable
produkt_kategorie = "Hygieneartikel" # lokale Variable
MWST = 1.19   # Konstante

Kommentare

Ruby kennt zwei Arten von Kommentaren. Mit dem #-Zeichen wird der Kommentar in einer Zeile gekennzeichnet. Dieser Kommentar kann am Anfang oder Ende einer Zeile beginnen. Mehrere zusammenhängende Zeilen werden auskommentiert, indem man den auszukommentierenden Bereich mit den Befehlen =begin und =end umschließt, wobei die beiden Schlüsselwörter ohne Leerzeichen am Anfang einer Zeile stehen müssen. Natürlich hat man auch die Möglichkeit, jede Zeile einzeln mit einem #-Zeichen auszukommentieren.

mwst = 0.19 # Mehrwehrtsteuersatz
# Berechnung des Brutto
brutto = netto * (mwst+1)
=begin
  Die Berechnung der Gesamtkosten folgt
  im folgenden Abschnitt
=end

Rheinwerk Computing - Zum Seitenanfang

Objekte und Datentypen  Zur nächsten ÜberschriftZur vorigen Überschrift

Alle Daten in Ruby sind Objekte, also Instanzen von Klassen. Die Zeichenkette »Hallo Welt« ist z. B. eine Instanz der Klasse String. Im Folgenden sagen wir einfach: Die Zeichenkette ist vom Typ String.

Um zum Beispiel ein Objekt der Klasse String zu erzeugen, können wir Folgendes schreiben:

text = String.new("Mein Text")

Es ist jedoch auch folgende Schreibweise möglich:

text = "Mein Text"

Kurzschreibweise

Dabei handelt es sich um die Kurzschreibweise, die bei der Erzeugung von Objekten der Standarddatentypenklassen, wie Strings , Arrays usw., zum Einsatz kommt. Die Klassen der Standardtypen werden über die Core-Bibliothek bereitgestellt, das heißt, sie stehen überall im Programm zur Verfügung, ohne explizit eingebunden werden zu müssen.

Innerhalb einer Klasse werden alle Methoden definiert, die auf ein Objekt angewendet werden können, die Klasse bestimmt also, welche Methoden auf ein Objekt anwendbar sind.

Auf Objekte der Klasse String können Sie z. B. die folgenden Methoden anwenden:

text = "Mein Text"
text.length
=> 9
text.upcase
=> "MEIN TEXT"
text.gsub("Mein","Dein")
=>"Dein Text"

Um den Typ eines Objekts oder einer Variablen zu erfragen, verwendet man die Methode class:

irb --simple-prompt
>> "Hallo Welt".class
=> String
>> satz = "Hallo Welt"
=> "Hallo Welt"
>> satz.class
=> String

Keine Deklaration von Variablen

Variablen werden, wie in den meisten anderen Skriptsprachen auch, nicht explizit deklariert, sondern einfach verwendet, indem man ihnen einen Wert zuweist. Die Variable nimmt dann automatisch den Datentyp des ihr zugewiesenen Wertes an. Diese Werte können z. B. vom Typ String, Fixnum, Float, Array oder Symbol sein:

irb --simple-prompt
>> preis = 12
=> 12
>> preis.class
=> Fixnum
>> mwst = 0.19
=> 0.19
>> mwst.class
=> Float
>> ausgabe = "Die Mehrwertsteuererhoehung macht sich bemerkbar"
=> "Die Mehrwertsteuererhoehung macht sich bemerkbar"
>> ausgabe.class
=> String
>> farbe = :rot
=> :rot
>> farbe.class
=> Symbol
>> zahlen = [1,2,3]
=> [1, 2, 3]
>> zahlen.class
=> Array

Methoden aufrufen

Methoden werden angewendet, indem man den Methodennamen mit einem Punkt an das Objekt oder die Variable, die das Objekt enthält, anhängt.

In Ruby ist das Setzen der runden Klammern beim Methodenaufruf optional ist, selbst dann, wenn einer Methode Parameter übergeben werden.

irb(main):003:0> string.length()
=> 13

Um z. B. die Länge einer Zeichenkette zu bestimmen, verwendet man die Methode length:

irb --simple-prompt
>> "Hallo Welt".length
=> 10
>> begruessung = "Hallo Welt"
=> "Hallo Welt"
>> begruessung.length()
=> 10
>> begruessung.length
=> 10

Nicht jede Methode kann auf jedes Objekt angewendet werden. So ist die Methode length auf Zahlen-Objekte nicht anwendbar. Die irb gibt im Beispiel einen »NoMethodError« zurück.

irb --simple-prompt
>> 13.length
NoMethodError: undefined method `length' for 13:Fixnum
    from (irb):6
    from :0

Zur Bestimmung aller Methoden, die auf ein Objekt anwendbar sind, verwendet man die Methode methods:

irb --simple-prompt
>> "Hallo Welt".methods
=> ["respond_to?", "%", "index", "select", "<<",
"to_a", "oct", "slice", "type", "chomp", "length",
"protected_methods", "upcase", "partition", "sub!",
...
"[]", "strip!", "kind_of?", "rjust", "[]="]

In der Liste findet man auch die Methode length wieder.

Methoden mit true/false- Rückgaben

Methoden, die true oder false zurückliefern, besitzen ein Fragezeichen am Ende. Das Fragezeichen gehört zum Namen der Methode. Dies ist eine Konvention in Ruby und sollte bei eigenen Methodendefinitionen strikt eingehalten werden, obwohl es auch möglich wäre eine Methode, die true oder false zurückgibt, ohne Fragezeichen am Ende zu definieren.

irb --simple-prompt
>> "".empty?
=> true
>> " ".empty?
=> false
>> "Mein Rails-Buch".include? "Rails"
=> true
>> "Mein Rails-Buch".include? "rails"
=> false
>> 8.zero?
=> false
>> 0.zero?
=> true

Überprüfen des Inhalts

Die Methode empty? bestimmt, ob eine Zeichenkette leer ist. include? prüft, ob eine Zeichenkette in einer anderen enthalten ist. Mit der Methode zero? wird bei Zahlen-Objekten überprüft, ob die Zahl 0 ist oder nicht.

Methodenaufrufe aneinanderreihen

Sehr praktisch ist, dass man in Ruby mehrere Methoden hintereinander auf ein Objekt anwenden kann, indem man die einzelnen Methoden durch einen Punkt getrennt aneinanderreiht. Die Klasse der Länge einer Zeichenkette ist beispielsweise vom Typ Fixnum , da die Zeichenlänge eine Zahl ist.

irb --simple-prompt
>> "Hallo Welt".length.class
=> Fixnum

Zahlen

Zahlen werden wie in anderen Programmiersprachen definiert: Ganzzahlen, z. B. preis = 12, und Kommazahlen, z. B. mwst = 0.19 . Da es sich auch bei Zahlen um Objekte handelt, können auf sie genau wie auf alle anderen Objekte, Methoden angewendet werden. Zum Beispiel liefert -123.abs den Absolutbetrag 123:

irb --simple-prompt
>> -123.abs
=> 123

Um mehrere Objekte zusammenzufassen, können Arrays und Hashes verwendet werden.

Arrays

Arrays bzw. Felder speichern mehrere Objekte geordnet ab. Der Zugriff auf die Elemente des Arrays erfolgt über einen ganzzahligen (0 oder höher) Index bzw. Schlüssel.

produkte = ['Apfel','Birne','Banane']
puts produkte[0]
=> Apfel
puts produkte[1]
=>Birne
puts produkte[2]
=>Banane
puts produkte[3]
=>nil
produkte[3]="Pflaume"
puts produkte[3]
=>Pflaume
puts produkte.length
=>4

Die Elemente des Arrays können verschieden sein, z. B. kann das Array selbst wieder Array-Objekte enthalten.

liste = [12,'Text',['Apfel','Birne','Banane']]
puts liste[2][1]
=> Birne

Hashes

Hashes können ähnlich wie Arrays mehrere Objekte aufnehmen. Jedoch wird jedes Element einem Schlüssel zugeordnet.

Der Zugriff auf die Elemente erfolgt ähnlich wie bei Arrays über einen Schlüssel, mit dem Unterschied, dass der Schlüssel ein beliebiges Objekt sein darf. Im folgenden Beispiel werden Zeichenketten als Schlüssel verwendet.

preise = { "apfel"=>1.50, "birne"=>1.99}
puts preise["apfel"]
=>1.50
puts preise["pflaume"]
=>nil
preise["pflaume"]=0.50
puts preise["pflaume"]
=>0.50

Rheinwerk Computing - Zum Seitenanfang

Verzweigungen  Zur nächsten ÜberschriftZur vorigen Überschrift

Im Programmieralltag kommt es aufgrund von Bedingungen immer wieder zu Verzweigungen innerhalb des Programms. Ruby unterscheidet, wie andere Programmiersprachen auch, die einfache Verzweigung (if) und Mehrfachverzweigungen (case).

Im folgenden Beispiel wird der Text >>kochend<< ausgegeben, wenn die Variable temperatur größer/gleich 100 ist:

temperatur = 120
if temperatur >= 100
  puts "kochend"
end

Da nur eine Anweisung ausgeführt wurde, hätte auch die einzeilige Schreibweise genutzt werden können:

puts "kochend" if temperatur >= 100

Leerzeichen statt Tabulatoren

Es ist in Ruby üblich, dass die Einrückungen aus zwei Leerschritten bestehen, nicht aus der >>normalen<< Tab-Weite. In den meisten Editoren ist die Tab-Weite aber änderbar, so dass man praktischerweise weiterhin die Tab-Taste für die Einrückungen verwenden kann.

else

Falls die if -Bedingung nicht zutrifft, wird der else -Zweig, falls vorhanden, ausgeführt:

temperatur = 120
if temperatur >= 100
  puts "kochend"
else
  puts "noch nicht kochend"
end

elsif

Verkettungen mit elsif sind möglich:

temperatur = 120
if temperatur >= 100
  puts "kochend"
elsif temperatur >= 50
  puts "heiss"
else
  puts "kalt"
end
Ja, elsif schreibt man in Ruby wirklich ohne >>e<< in der Mitte. Bei uns hat es einige Fehlermeldungen gebraucht, bis wir uns daran gewöhnen konnten.

Ternärer Operator

Ruby kennt auch wie C und Java den ternären Operator, der es ermöglicht, eine if-else-Bedingung in einer Zeile zu formulieren:

liste = ['Apfel', 'Birne']
status = liste.size==0 ? "leer" : "gefuellt"
puts "liste ist #{status}"
# => "liste ist gefuellt"

Boolesche Verknüpfungen

Innerhalb der Bedingungsformulierung sind auch sog. boolesche Verknüpfungen wie Und-Verknüpfungen (&&) oder Oder-Verknüpfungen (||) möglich. Zur Gruppierung einzelner Teilbedingungen können runde Klammern eingesetzt werden. Die Negierung einer Bedingung erfolgt durch ein vorangestelltes Ausrufezeichen:

temperatur_1 = 120
temperatur_2 = 80

# Und-Verknüpfung
if temperatur_1 >= 100 && temperatur_2 >= 100
  puts "beide kochend"
end

# Oder-Verknüpfung
if temperatur_1 >= 100 || temperatur_2 >= 100
  puts "mindestens einer kochend"
end
if !(temperatur_1 >= 100 || temperatur_2 >= 100)
  puts "keiner kochend"
end

unless

Die Negierung einer Bedingung kann in Ruby auch über den Ausdruck unless ausgedrückt werden. Die beiden folgenden Verzweigungen sind identisch:

temperatur = 80
unless temperatur >= 100
  puts "nicht kochend"
end

if !(temperatur >= 100)
  puts "nicht kochend"
end

Auch für unless gibt es eine einzeilige Schreibweise, wenn nur eine Anweisung ausgeführt wird:

puts "nicht kochend" unless temperatur >= 100

Mehrfach- verzweigung

Falls Sie mehr als zwei Verzweigungen benötigen, um den Wert einer Variablen auf Gleichheit mit verschiedenen Werten zu prüfen, können Sie die case-Verzweigungen (Mehrfachverzweigungen) nutzen:

versandart = "10-Kilo-Paket"
case versandart
when "Standardbrief"
  preis = 0.55
when "Postkarte"
  preis = 0.45
when "5-Kilo-Paket","10-Kilo-Paket"
  preis = 6.90
else
  preis = nil # kein Wert
end
puts "Preis fuer #{versandart} betraegt #{preis} EUR"
# Ausgabe: Preis fuer 10-Kilo-Paket betraegt 6.9 EUR

Interessant ist: Soll für mehrere Fälle die gleiche Anweisung ausgeführt werden, können diese Fälle in einem when durch Komma getrennt angegeben werden (when "5-Kilo-Paket","10-Kilo-Paket").


Rheinwerk Computing - Zum Seitenanfang

Überprüfen auf Gleichheit  Zur nächsten ÜberschriftZur vorigen Überschrift

equal?

In Ruby gibt es mehrere Methoden zur Prüfung auf Gleichheit. Bei der Prüfung auf Gleichheit sind immer genau zwei Objekte beteiligt.

Die Methode equal? prüft, ob es sich um dieselben Objekte mit der gleichen Objekt-ID handelt. "Hans".equal? "Hans" liefert z. B. false, da es sich bei den beiden Zeichenketten um verschiedene Objekte handelt, obwohl sie den gleichen Inhalt haben.

"Hans".object_id
=> 214670
"Hans".object_id
=> 207040
"Hans".equal? "Hans"
=> false

Gleiche Ganzzahlen

Wenn man das letzte Beispiel betrachtet, könnte man auch erwarten, dass Zahlen bei gleichem Wert auch verschiedene Objekt-IDs haben. Dem ist jedoch zumindest bei Ganzzahlen nicht so, wie folgendes Beispiel zeigt:

1.object_id
=> 3
1.object_id
=> 3
1.equal? 1
=> true

Gleiche Fießkommazahlen

Das Kuriose ist jedoch, dass die gleichen Fließkommazahlen (Float) unterschiedliche Objekt-IDs besitzen:

1.0.object_id
=> 168900
1.0.object_id
=> 150630
1.0.equal? 1.0
=> false

Bei komplexeren Objekten gilt:

class Guest
  attr_accessor :name
end
guest1 = Guest.new
guest2 = Guest.new
guest1.name = "Hans"
guest2.name = "Hans"
guest1.equal? guest2
=> false

Um nur zu überprüfen, ob die Werte beider Objekte gleich sind, wird die Methode == verwendet. In anderen Programmiersprachen würden wir sagen, dass es sich bei == um einen (Vergleichs-)Operator handelt. In Ruby ist es jedoch eine Methode, wie die Schreibweise "Hans".==("Hans") zeigt. Glücklicherweise ist folgende Schreibweise ebenfalls erlaubt und auch üblich:

"Hans" == "Hans"
=> true
guest1.name == guest2.name
=> true
1 == 1.0
=> true

eql?

Das letzte Beispiel zeigt, dass der Typ der Objekte nicht notwendigerweise übereinstimmen muss. Um festzustellen, dass sowohl die Werte also auch der Typ der Objekte gleich sind, kann die Methode .eql? eingesetzt werden:

1.eql? 1.0
=> false

Rheinwerk Computing - Zum Seitenanfang

Schleifen  Zur nächsten ÜberschriftZur vorigen Überschrift

Um mehrere Anweisungen wiederholt auszuführen, bietet Ruby mehr Möglichkeiten als viele andere Programmiersprachen. Aber lassen Sie uns mit den aus anderen Sprachen bekannten Schleifenkonstrukten anfangen.

while-Schleife

Um Anweisungen in Abhängigkeit von einer Bedingung auszuführen, kann die while -Schleife oder die until -Schleife verwendet werden. Im folgenden Beispiel wird errechnet, wie viele Jahre man sparen muss, um ein bestimmtes Zielguthaben zu erreichen:

zinssatz = 0.05
betrag = 1000
ziel_betrag = 2000
jahre = 0
while betrag < ziel_betrag
  betrag = betrag * (1+zinssatz)
  jahre += 1  # Abkürzung für jahre = jahre + 1
end
puts "Sie muessen #{jahre} Jahre sparen"
# Ausgabe: Sie muessen 15 Jahre sparen

until-Schleife

Es hätte auch eine until -Schleife eingesetzt werden können. Die until-Schleife wird im Gegensatz zur while -Schleife nicht so lange wiederholt, wie eine Bedingung erfüllt ist, sondern so lange, bis eine Bedingung erfüllt ist:

zinssatz = 0.05
betrag = 1000
ziel_betrag = 2000
jahre = 0
until betrag >= ziel_betrag
  betrag = betrag * (1+zinssatz)
  jahre += 1
end
puts "Sie muessen #{jahre} Jahre sparen"
# Ausgabe: Sie muessen 15 Jahre sparen

Um z. B. Arrays zu durchlaufen, gibt es auch in Ruby die for-Schleife:

einkaufsliste=["Mehl","Zucker","Wasser"]
for produkt in einkaufsliste do
  puts produkt
end
# Ausgabe:
# Mehl
# Zucker
# Wasser

for-Schleife

Eine for-Schleife mit einem Schleifenzähler, so wie in PHP oder Java, existiert in Ruby nicht. Dafür aber etwas viel Besseres: Iteratoren.

Alternative zu for

Deshalb ist in Ruby folgende Schreibweise für eine for-Schleife üblich:

einkaufsliste=["Mehl","Zucker","Wasser"]
einkaufsliste.each do |produkt|
  puts produkt
end

Iteratoren

Interessant ist hier die Schreibweise. Das Array-Objekt einkaufsliste gefolgt von einem Punkt und dem each sieht nicht nur aus wie ein Methodenaufruf, sondern es ist ein Methodenaufruf. Methoden, die für Schleifen zur Verfügung stehen, werden Iteratoren genannt. each ist ein Iterator von Array-Objekten. Die Methode times ist z. B. ein Iterator für Ganzzahlen-Objekten:

5.times do
  print "*"
end
# ausgabe: *****

Da in beiden Beispielen nur eine Anweisung ausgeführt wurde, hätte auch die einzeilige Schreibweise eingesetzt werden können:

einkaufsliste=["Mehl","Zucker","Wasser"]
einkaufsliste.each {|produkt| puts produkt}

5.times {print "*"}

Rheinwerk Computing - Zum Seitenanfang

Klassen  topZur vorigen Überschrift

Klassen erstellen Objekte

Wie bereits vorher beschrieben, sind alle Daten in Ruby Objekte, also Instanzen von Klassen. Das heißt, Klassen dienen in den meisten Fällen dazu, Objekte zu erstellen. Eine Klasse stellt in gewisser Weise eine »Fabrik« dar, mit der gleichartige Objekte erzeugt werden. Man sagt auch, dass eine Klasse Objekte instantiiert.

Innerhalb einer Klasse werden alle Methoden definiert, die auf ein Objekt angewendet werden können, das heißt, die Klasse bestimmt, welche Methoden auf ein Objekt anwendbar sind. Bei der Entwicklung einer Webapplikation mit Rails können wir aber nicht nur mit Klassen arbeiten, die uns Ruby zur Verfügung stellt, sondern wir müssen auch eigene Klassen erstellen können:

Operatoren sind Methoden

Besonders interessant in Ruby ist, dass sogar Operatoren wie +, -, *, /, =, << und >> Methoden sind. Um z. B. zwei Zeichenketten miteinander zu verbinden, existiert die Methode +:

text1 = "Ruby"
text2 = "OnRails"
text = text1.+(text2)
=> "RubyOnRails

Da die Schreibweise ».+« sehr merkwürdig aussieht, erlaubt Ruby es, den Punkt beim Aufruf der Methoden +, -, *, /, =, << und >> wegzulassen:

text1 = "Ruby"
text2 = "OnRails"
text = text1 + text2
=> "RubyOnRails

Dies gilt aber nur für diese Methoden! Bei allen anderen, wie z. B. der Methode length, muss der Punkt beim Aufruf der Methode gesetzt werden.

Eigene Klassen

Bisher haben wir Ihnen den Einsatz von Klassen, die von Ruby zur Verfügung gestellt werden, gezeigt. Doch das reicht nicht aus. Wir müssen auch eigene Klassen erstellen können.

Beispiel

Im Folgenden werden wir die Klasse Produkt erstellen. Innerhalb der Klasse Produkt werden die Methoden name und preis definiert, das heißt, jedes Objekt der Klasse Produkt repräsentiert ein Produkt mit einem Namen und einem Preis. Bevor wir die Klasse definieren, zeigen wir, wie wir diese Klasse verwenden möchten:

apfel = Produkt.new
apfel.name = "Elsta"
apfel.preis = 0.99
puts "Der Preis von #{apfel.name} betraegt #{apfel.preis} EUR"
=> "Der Preis von Elsta betraegt 0.99 EUR"
buch = Produkt.new
buch.name = "Ruby on Rails"
buch.preis = 38.99
gesamt  = apfel + buch
puts "Der Gesamtbetrag ist #{gesamt} EUR"
=> "Der Gesamtbetrag ist 39.98 EUR"

Neues Objekt erstellen

Mit dem ersten Befehl Produkt.new wird ein neues Objekt erstellt. Die zweite Anweisung sieht so aus, als ob wir auf ein Attribut (oder eine Variable) des Objekts zugreifen. Dem ist nicht so. apfel.preis=0.99 ist eine Abkürzung für apfel.preis=(0.99).

Das heißt, name= (inkl. des Gleichheitszeichens) ist der Name der Methode und 0.99 ist der Übergabeparameter. Um den Preis eines Objekts der Klasse Produkt auszugeben, schreiben wir apfel.preis . Auch hier ist preis eine Methode. Deshalb hätten wir auch apfel.preis() schreiben können. In Java hätte man die Methoden name= und name setName und getName genannt. Weil diese Methoden die Attribute eines Objektes setzen oder abfragen, nennt man sie auch setter-getter-Methoden .

Implementierung

Kommen wir nun zur Implementierung der Klasse:

class Produkt
  def name=(bezeichnung)
    @name = bezeichnung
  end

  def name
    return @name
  end

  def preis=(wert)
    @preis = wert
  end

  def preis
    return @preis
  end

  def +(produkt)
    return @preis + produkt.preis
  end

end

Instanzvariablen

Die Klasse verwendet zwei Instanzvariablen: @name und @preis . Erkennen können Sie die Instanzvariablen am vorangestellten @ -Zeichen. Instanzvariablen werden für jedes Objekt (bzw. jede Instanz) der Klasse individuell gespeichert, das heißt, das Objekt apfel und das Objekt buch haben jeweils andere Werte in ihrer Instanzvariablen @name gespeichert.

Instanzvariablen dienen also der Speicherung von Daten separat für jedes Objekt. Kein anderes Objekt kann direkt auf die Instanzvariable eines anderen Objekts zugreifen.

Die Funktionsweise der Methoden name=, name, preis= und preis haben Sie schon bei der Verwendung der Klasse Produkt weiter oben kennengelernt. Die Methode + addiert den Preis des (eigenen) Objektes mit dem Preis-Attribut des übergebenen Objektes.

Hätten wir die + -Methode nicht definiert, so müssten wir zum Addieren die Attribute preis ansprechen.

gesamt  = apfel.preis + buch.preis
puts "Der Gesamtbetrag ist #{gesamt} EUR"
=> "Der Gesamtbetrag ist 39.98 EUR"

Es ist auch möglich, direkt beim Erstellen eines neuen Objekts Instanzvariablen zu initialisieren. Im folgenden Beispiel werden der Name und der Preis beim Erstellen eines neuen Produkt-Objekts festgelegt.

class Produkt

  def initialize(bezeichnung,preis)
    @name = bezeichnung
    @preis = preis
  end

  def name
    return @name
  end

  def preis
    return @preis
  end

  def +(produkt)
    return @preis + produkt.preis
  end

end

initialize

Die Methode initialize wird aufgerufen, wenn ein neues Objekt erzeugt wird. Das heißt, die Methode new der Klasse Produkt ruft intern die Methode initialize auf:

apfel = Produkt.new("Elsta",0.99)
puts "Der Preis von #{apfel.name} betraegt #{apfel.preis} EUR"
=> "Der Preis von Elsta betraegt 0.99 EUR"

buch = Produkt.new("Ruby on Rails",38.99)
gesamt  = apfel + buch
puts "Der Gesamtbetrag ist #{gesamt} EUR"
=> "Der Gesamtbetrag ist 39.98 EUR"

Die Klasse Produkt haben wir erstellt, um Instanzen von allgemeinen Produkten erstellen zu können. Aber was ist, wenn wir zu einem Buch z. B. auch die ISBN-Nummer speichern möchten, die ja kein Merkmal eines allgemeinen Produktes darstellt? Eine Möglichkeit wäre, die Klasse Produkt zu kopieren, die Methoden isbn=() und isbn() zu ergänzen und die Klasse unter einem neuen Namen, z. B. Buch, zu speichern.

Vererbung

Die sog. Vererbung unter Klassen bietet ein besseres Konzept:

Wir erstellen eine neue Klasse Buch, die eine Kindklasse von Produkt ist. Das heißt, Buch erbt alle Methoden und Instanzvariablen der Klasse Produkt und stellt zusätzlich eigene Methoden zu Verfügung (isbn=() und isbn()):

class Buch < Produkt

  def isbn=(nummer)
    @isbn = nummer
  end

  def isbn
    return @isbn
  end

end

buch = Buch.new("Ruby on Rails", 39.90)
buch.isbn = "978-3-89842-779-1"
Automatische setter-getter-Methoden
Ruby kann die setter-getter-Methoden auch automatisch erstellen, wenn die Methode attr_accessor aufgerufen wird. Die Buch-Klasse kann dann wie folgt abgekürzt werden:
class Buch < Produkt
  attr_accessor :isbn
end


Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen. >> Zum Feedback-Formular
 <<   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: Ruby on Rails 3.1






 Ruby on Rails 3.1


Zum Katalog: Responsive Webdesign






 Responsive Webdesign


Zum Katalog: Suchmaschinen-Optimierung






 Suchmaschinen-
 Optimierung


Zum Katalog: JavaScript






 JavaScript


Zum Katalog: Schrödinger lernt HTML5, CSS3 und JavaScript






 Schrödinger lernt
 HTML5, CSS3
 und JavaScript


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
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.


[Rheinwerk Computing]

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