Übersicht ||
0:Vor |
1:Ge |
2:Theo |
3:Var |
4:Op |
5:IO |
6: Ablaufstrukturen |
7: Subroutinen |
8: Objekte |
9:Rx ||
A:Index |
B:Tab |
C:Tour |
D:Delta |
E:Links
Grundlagen
sub-Befehl
Eine Subroutine ist ein Stück Quelltext dem man einen Namen geben kann und daß mit diesem Namen aufgerufen werden kann. In Perl ist der Block einer Subroutine in geschweifte Klammern gefasst und fängt immer mit dem Befehl
sub an, gefolgt von dem Namen der Subroutine und zuletzt der Block.
sub MJD_sagt { say "Premature optimization is the root of all evil." }
MJD_sagt(); # Aufruf der Subroutine
MJD_sagt; # geht auch
&MJD_sagt; # geht nicht mehr, liefert Referenz auf sub
yadda-Operatoren
sub MJD_sagt {} # ERROR
sub MJD_sagt {...} # so gehts, ruft fail
sub MJD_sagt {???} # ruft warn
sub MJD_sagt {!!!} # ruft die
Ja, das erste Beispiel dieses Kapitels ist eine der denkbar einfachsten Subroutinen, denn Subroutinen mit leeren Blöcken sind nicht mehr erlaubt. Der Interpreter wird dich mit einer Fehlermeldung daran erinnern. Wenn du aber Perl zeigen willst daß der leere Block kein Versehen ist, weil du noch nicht weisst was du eintragen willst, benutz den yadda yadda yadda (deutsch bla bla bla) Operator, der aus 3 zusammenhängenden Punkten besteht, aber auch mit 3 Fragezeichen (erzeugt Warnung) oder Ausrufezeichen(Abbruch) geschrieben werden kann.
anonyme Subs
Da man Referenzen auf Subroutinen auch in Skalaren speichern kann, lassen sich die Subroutinen über diesen Umweg aufrufen. Und weil der ursprüngliche Name der sub dabei bedeutungslos wird, kann man ihn auch weglassen, wenn man die sub nur über die Referenz aufrufen will. (SubBlock)
$spruch = &MJD_sagt; # Übergabe der Referenz
$spruch = sub { ... } # macht das selbe direkter
$spruch = { ... } # dito; Tip: keinen semikolons nach } notwendig
$spruch; # Aufruf
$subref('spruch'); # mit Parameter
pointy sub
Der
pointy block Syntax läßt sich natürlich auch für Subroutinen benutzen die dann "pointy sub" genannt werden.
Rueckgabewerte
Eine Subroutine nennt man oft Funktion, wenn sie ein Ergebnis liefert. In Perl gibt es diese Unterscheidung natürlich weiterhin nicht, da jede sub das Ergebnis seiner letzten Anweisung als Rückgabewert liefert. Um dies lesbarer herauszustellen kann man vor den letzten Befehl ein
return setzen. Innerhalb einer sub erzwingt der
return Befehl den vorzeitigen Abbruch der sub, wobei auch der folgenden Werte zurückgegeben werden. Der Typ dieser Werte wird gegen die Signatur gemachted, soweit dort Typen für Rückgabewerte defiert sind.
sub gib_mir_5 { return int rand 10000 } # liefert Zufallzahl von 0 bis 10.000,
sub gib_mir_5 { int rand 10000 } # ergebnisgleiche sub
$zahl = gib_mir_5; # KLF: dont take 5, take what you want to ...
print 'Und die Zahl des heutigen Abends ist ...' ~ gib_mir_5 ~ ".\n";
Signaturen
Positionale Parameter
Eines der wichtigsten und besten Neuerungen sind benannte Parameter (Werte die man an eine sub übergibt), die auch gleich in der Signatur
typisiert oder mit
Traits versehen werden können. Als Signatur bezeichnet man die Definition der Parameter, die hier in runden Klammern, direkt nach dem Schlüsselwort
sub und vor dem Block erfolgt. Durch das Weglassen der Signatur kann man aber immernoch im alten Perl5-Stil weiterprogrammieren.
sub ($a, $b) {
}
sub ($a, *@b) {
}
Optionale Parameter
Benannte Parameter
Multisubroutinen
Damit kann man kurz gesagt Subroutinen schaffen, die je nach dem, was man ihnen übergibt, unterschiedliche Dinge tun können. Multisubroutinen sind meist mehrere Subs die sich einen Namen teilen. Ruft man diesen auf, prüft Perl, ob die übergebenen Parameter mit der Signatur einer der Multisubroutinen übereinstimmt. Wenn ja wird diese aufgerufen. Das berühmte Quicksortbeispiel ist nun in Perl genauso kurz wie in Haskell. Und zum schnellen verstehen noch etwas zur Berechnung der Fakultät.
multi qsort ( [ ] ) { return () }
multi qsort ( [$h, *@t] ) {
my @a := grep { $_ le $h } @t;
my @b := grep { $_ gt $h } @t;
return qsort(@a), $h, qsort(@b);
}
multi fakultaet ( 0) { 1 }
multi fakultaet (Int $i) { $i * fakultaet($i - 1) }
Currying
sub multiply ($multiplicand, $multiplier) {
return $multiplicand * $multiplier;
}
$six_times = &multiply.assuming(multiplier => 6);
umhüllte Routinen
$id = &subname.wrap ({
# [parameter] vorbereiten
$return = callwith();
# oder callsame bei unveränderten parametern
# [ergebnis] nachbereiten
})
# rufe umüllte version
subname();
# hebe Umhüllung auf
&subname.unwrap($id);
Umhüllungen dürfen beliebig verschachtelt werden.
Namensräume
Scope
Pakete
Module
Macros
Macros sind besondere Subroutinen die bereits zur Startzeit (Compiletime) ausgeführt werden, so in etwas wie die alten BEGIN{} - Blöcke, nur das Makros wesentlich mächtiger sind und die Sprache selber ändern können, und damit Sourcefilter überflüssig machen. (Die werden auch abschafft.) Egal ob mehreilige Kommentare, einen Wurzeloperator, alles was du schon immer in Perl haben wolltest kannst du nun in Perl6 mit einem kleinen Makro hinzufügen.
Übersicht ||
0:Vor |
1:Ge |
2:Theo |
3:Var |
4:Op |
5:IO |
6: Ablaufstrukturen |
7: Subroutinen |
8: Objekte |
9:Rx ||
A:Index |
B:Tab |
C:Tour |
D:Delta |
E:Links
--
HerbertBreunung - 03 Apr 2006
--
ChristophBussenius - 21 May 2006 - Rechtschreibung etc.