Perl 6

Die Zukunft des Programmierens

Das Objektmodell von Perl 6

Um von dieser Seite profitieren zu können, sollten Sie mit den Grundlagen von Perl 6 vertraut sein, und auch ein wenig von Objektorientierung verstehen - wenn Sie wissen, was eine Klasse, ein Objekt und Vererbung ist, reicht das vermutlich schon.

Das Objektmodell von Perl 6 hat nur noch wenige Ähnlichkeiten mit dem von Perl 5, und muß jetzt den Vergleich mit "klassischen" objektorientierten Programmiersprachen nicht mehr scheuen.

Klassen definieren

Klassen werden mit dem class-Schlüsselwort definiert, das man auf zwei verschiedene Arten verwenden kann. Entweder als erste Anweisung in einer Datei in der Form class MeineKlasse;, dann ist der Rest der Datei die Definition der Klasse. Die zweite Möglichkeit sieht so aus:

class MeineKlasse {
	# hier kommt die Definition der Klasse
}
# hier ist die Definition der Klasse zu Ende
# und anderer Code kann hier stehen.

Objektvariablen (auch Attribute genannt) werden mit has anstatt my deklariert, und haben nach dem Sigil (also $, @, %) noch ein weiteres Sonderzeichen, ein Ausrufezeichen. Jedes Objekt einer Klasse hat seine eigene Kopie jeden Attributs. Methoden werden mit method anstatt sub deklariert:

class Rechteck {
	has $!breite;
	has $!hoehe;

	method flaeche {
		return $!breite * $!hoehe;
	}
}

# benutze den Standardkonstruktor
my $r = Rechteck.new(:hoehe(5), :breite(3));

say $r.flaeche;     # 15

Attribute sind privat, das heisst Code ausserhalb der Klasse hat keinen Zugriff auf sie. Häufig ist das aber erwünscht, daher gibt es eine einfache Syntax, um sie von aussen mithilfe einer Methode verfügbar zu machen:

class Rechteck {
	has $.breite;
	has $.hoehe;

	method flaeche {
        # Die Namen der Attribute enthalten immer noch
        # das Ausrufezeichen
		return $!breite * $!hoehe;
	}
}
my Rechteck $r = Rechteck.new(:breite(5), :hoehe(3));
say $r.flaeche;         # 15
say $r.hoehe;           # 3
say $r.breite;          # 5

Manchmal sollen die Attribute auch von aussen beschreibbar sein, dann fügt man den Trait is rw an:

class Rechteck {
	has $.breite is rw;
	has $.hoehe is rw;

	method flaeche {
		return $.breite * $.hoehe;
	}
}
my Rechteck $r = Rechteck.new();
$r.breite = 2;
$r.hoehe = 5;
say $r.flaeche();

Private Methoden funktionieren mit der Syntax method !meine_methode, und können mit self!meine_methode aufgerufen werden.

class Auto {
    has $!motor;
    has $!gang;

    method !gang_wechseln ($differenz) {
        $!gang += $differenz;
    }
    ...


    method beschleunigen {
        self!gang_wechseln(-1);
        # hier gas geben
        self!gang_wechseln(+1);
    }
}

Vererbung

Vererbung wird durch das is-Schlüsselwort deklariert:

class Form {
	...
}

class Rechteck is Form {
	...
}

Auch Mehrfachvererbung ist möglich:

class Kraftfahrzeug {
	...
}

class Wasserfahrzeug {
	...
}

class Amphibienfahrzeug is Kraftfahrzeug is Wasserfahrzeug {
	...
}

(Beispiel aus der Wikipedia)

Vererbung und andere is ...-Traits kann man auch innerhalb der Klasse schreiben:


class Amphibienfahrzeug {
	is Kraftfahrzeug;
	is Wasserfahrzeug;
	...
}

Klassen erweitern

Wenn man eine Klasse erweitern will, ihr zum Beispiel eine Methode hinzufügen will, kann man das auch ohne Vererbung erreichen:

augment class String {
	method as_ebcdic {
		...
	}
}

Das hat den Vorteil, dass man auch fest eingebaute Datentypen wie String oder Int erweitern kann, und fremder Code, den man einbindet, verwendet automatisch die erweiterte Version. Allerdings können Erweiterungen in einem Teil eines Programms mit Erweiterungen in weit entfernten Programmteilen kollidieren - daher gelten sie als sehr schlechter Stil.

Wenn man versucht, eine Klasse zu erweitern, ohne ein is also in die Deklaration zu schreiben, bekommt man eine Fehlermeldung, dass man eine Klasse redeklariert.

Roles

In Perl 6 sind Klassen vor allem dazu da, um "ist-ein"-Beziehungen für Typen zu deklarieren. Für die Wiederverwendbarkeit von Code sind Roles, auf Deutsch Rolle zuständig. Roles sind so etwas wie Interfaces in Java, die Implementierung der Methoden beinhalten.

Genauer gesagt kann eine Role alles enthalten, was eine Klasse auch enthalten kann, nur kann man keine Objekte einer Role erstellen.

role Haustier {
	has $.halsband;
	method halsband_loesen {
		undefine $.halsband;
	}
	...
}

class Hund is Saeugetier does Haustier {
	...
}

Wie das Beispiel zeigt, inkorporiert eine Klasse eine Rolle mit dem Schlüsselwort does.