Perl 6 Tutorial Part 4




Still operators left?

Nach "Operatoren f�r Skalare" und "Operatoren f�r Arrays" ist sicher "Operatoren
f�r Hashes" der n�chste logische Titel. Nur leider gibt es keine speziellen
Operatoren f�r Hashes in Perl 6. Au�er vielleicht den "dicken Pfeil" ("fat arrow").
�hnlich dem Komma, da� einen Array erzeugt, weist der "=>" den Interpreter an,
einen Hash zu bilden. Deswegen wird er auch manchmal "hash composer" genannt.

Perl 6:
$ziffern = (7); # Zuweisung eines Wertes
$ziffern = 7,; # Referenz auf einen Array
%ziffern = 1 => 'adin', 2 => 'dwa';
%ziffern = {1 => 'uno', 2 => 'due'}; # geht auch

Da runde Klammern nun nur noch gruppieren und geschweifte Klammern per default
einen anonymen Codeblock darstellen, braucht der Interpreter auch diesen Hinweis
um zu erkennen, da� der Programmierer gerne einen Hash h�tte. Weil geschweifte
Klammern dar�ber hinaus immernoch f�r Hashreferenzen stehen k�nnen, wird in der
letzten Beispielzeile eine solche erzeugt. Nur wird diese, anders als in Perl 5,
automatisch dereferenziert, wenn sie einem Hash zugewiesen wird. Dieses Prinzip
wurde in der letzten Folge schon anhand von Arrays demonstriert. In Perl 5 war der
"fat arrow" nur eine lustige Schreibweise f�r ein Komma. Es half dem Programmierer
zu erkennen da� hier ein Hash ensteht, aber er h�tte genauso gut schreiben k�nnen:

Perl 6:
%ziffern = (0, 'null', 1, 'eins');
%ziffern = {1, 'jeden', 2, 'dva'};

Dies funktioniert auch weiterhin wunderbar. Aber nicht weil nun Hashes immer noch
Arrays mit gerader L�nge sind, sondern weil es eine Regel gibt, wie der Array in
einen Hash(kontext) umgewandelt wird. Und ja, in der zweiten Zeile liefert ein
anonymer Block einen Array zur�ck. In diesem Beispiel st�rt das nicht.Aber es kann
zu sehr unerwarteten Ergebnissen f�hren, da syntaktisch gleiche Bl�cke in
Sonderf�llen andere R�ckgabewerte haben k�nnten. Um es eindeutig zu halten,
k�nnen die Operatoren C<%> und C<hash> den Hashkontext erzwingen und anzeigen.

Perl 6:
$hashref = hash{ 0, 'null', 1, 'eins' };
$hashref = %( 0, 'null', 1, 'eins' );
# oder klassisch:
$hashref = { '1' => 'a', '2' => 'b', 3 => 'c' };
# entspricht \('1' => 'a', '2' => 'b', 3 => 'c');
# oder auch %( 1..3 Z 'a'..'c' );

Ein Hash kann aber auch in einen anderen Kontext �berf�hrt werden. Im boolschen
Kontext meldet er, ob er �berhaupt Schl�ssel besitzt, im numerischen Kontext
die Anzahl der Schl�ssel und im Stringkontext gibt er seinen gesamten Inhalt als
String aus.

Perl 6:
my %buch = ( 1..3 Z 'a'..'c');
? %buch # Bool::True
+ %buch # 3, entspricht %buch.elems
~ %buch # "1\ta\n2\tb\n3\tc\n"

Weit praktischer ist aber meistens die Ausgabe der folgenden, selbsterkl�renden
Hashmethoden, welche einen Array zur�ckgeben.

Perl 6:
%buch.keys; # (1, 2, 3), entspricht keys %buch
%buch.values; # ('a', 'b', 'c'), auch values %buch
%buch.kv; # (1, 'a', 2, 'b', 3, 'c')

C<keys> und C<values> sind altbekannte Perl 5-Befehle, die es selbstverst�ndlich
auch weiterhin gibt. Aus ihren Initialien leitet sich der Name der Methode C<.kv>
ab, die abwechselnd zugeh�rige Schl�ssel und Werte in einem Array aufz�hlt. Etwas
anders funktioniert dagegen die Methode C<.pairs>. Sie liefert key und value in
einem Skalar, also einen Array von Wertepaaren. Das Gleiche erh�lt man auch, wenn
ein Hash einem Array zugewiesen wird.

Perl 6:
%buch.pairs; # (1 => 'a'), (2 => 'b'), (3 => 'c')
@buch = %buch; # dito

Werdet ein Paar

Key und value in einem Skalar? Das mag zuerst nach einem Array oder vielleicht
einer Junction klingen, ist aber einfach ein Wertepaar. Das Paar geh�rt zu den
v�llig neuen Datentypen, die Perl 6 einf�hrt. Eigentlich sind es auch Paare, die
mit dem "fat arrow" erzeugt werden. In den Synopsen wird "=>" desweg oft auch
"pair constructor" genannt.

Perl 6:
my $pair = 'Jakub' => 'Helena';
$pair.isa(Pair) # ergibt Bool::True
$pair.key # 'Jakub'
$pair.value # 'Helena'

Paare k�nnen aber auch noch anders generiert werden.

Perl 6:
my $pair = :Jakub('Helena'); # oder k�rzer:
my $pair = :Jakub<Helena>; # <> ist das neue qw()

Selbstverst�ndlich funktioniert auch diese Schreibweise f�r Hashes.

Perl 6:
%regent = :Atreides<Paul>, :Harkonnen<Wladimir>, :Ordo<Executrix>;
$hashref = {pair <Atreides Paul Harkonnen Wladimir Ordo Executrix> };

Allerdings dient das nicht der optischen Vielfalt, sondern zeigt, da� Paare mehr
Aufgaben haben, als Hashbausteine zu sein (obwohl sie dazu sehr geeignet sind).
Ungeordnete Listen von Wertepaaren mit eindeutigen Schl�sseln entsprechen sicher
eher der Idee eines Hashes als Listen mit gerader L�nge. Das n�chste Beispiel
ist ein bewu�t herbeigef�hrter Unfall, der die Schw�che von Perl 5 demonstriert.
Einzelne Werte die dem Hash entnommen wurden k�nnen jede Zugeh�rigkeit zwischen
den Schl�sseln und Werten zerst�ren.

Perl 5:
my %h = (1=>2, 3=>4);
%h = grep {$_ % 2} %h;
say %h; # {1 => 3 }

Zum Gl�ck wurde f�r Perl 6 auch diese Schmuddelecke aufger�umt.

Perl 6:
%h = grep {$_.value % 2} %h.pairs;

Diese Fassung macht nicht nur mehr Sinn, sondern ist auch noch lesbarer, da hier
explizit steht, was geschieht. Sie kann auch keine unsinnigen Ergebnisse liefern,
da korrekterweise immer Paare durchgereicht werden. Doch um zu beweisen da� die
neue Ordnung nicht einschr�nkt, hier das Perl 5-Beispiel im Perl 6-Syntax.

Perl 6:
%h = grep {$_ % 2} %h.kv;

Parameterpaare und $@%

Mit Paaren lassen sich wundersame Datenstrukturen wie Hybride aus Hash und Array
erzeugen oder Paarlisten, in denen Schl�ssel mehrfach vorkommen k�nnen. Aber die
wichtigste Verwendung von Paaren au�erhalb der Hashes sind benannte Parameter.
Diese wurden in Perl 5 oft mithilfe von Hashes simuliert. Jedoch bietet Perl 6
daf�r einen expliziten Mechanismus der viele interessante Techniken erm�glicht.
Subroutinen und Parameter�bergaben sind aber das Thema der n�chsten Folge. Doch
selbst "Kernfunktionen" der Sprache haben benannte Parameter, welche die zweite
Syntax der Paare benutzen. Die in Folge 2 vorgestellten Dateitestoperatoren
C<:r :w :e> sind nichts weiter als Attribute des Objektes vom Typ Filehandle.
Dabei dr�ckt die Formulierung C<:r> aus: "Ich h�tte gerne den Wert, der unter dem
Schl�ssel "r" gespeichert ist". �hnliches gilt auch beim �ffnen einer Datei.

Perl 6:
my $fh = open "datei.txt", :r;

Die Datei wird im Lesemodus ge�ffnet, indem der benannte Parameter "r" gesetzt
wird. In dem Beispiel f�llt auch auf, da� Filehandle kein eigener Variablentyp
sind und auch keinen eigenen Namensraum mehr besitzen. Auch Verzeichnishandler
und Formate werden nun in Skalaren gespeichert. Die Formate weichen dazu aus dem
Sprachkern in ein Modul. Auch Token wie C<__LINE__> oder C<__PACKAGE__>, die man
als Systemvariablen mit eigenem, sonderbaren Namensraum ansehen k�nnte, sind in
ihrer neuen Schreibweise C<$?LINE> und C<$?PACKAGE> eher als Variablen erkennbar.
Ihr seltsamer Namensraum nennt sich nun "compiler hint variables". Er umfasst
Informationen, die ab dem Zeitpunkt der Kompilierung feststehen und auch nicht
ge�ndert werden d�rfen. Eine Zuweisung wie C<$?FILE = 'was anderes';> w�rde einen
Compile-Error ausgeben. Dieser Sonderstatus wird mit der sekund�ren Sigil (Twigil)
"?" markiert. Achtung: In Perl 6 bezeichnet Token eine sehr einfache Form einer
Regex.

Die Streichung der 4 Sondernamensr�ume f�r Variablen (Handler, Formate und Token)
sind weitere Beispiele des Grundsatzes: "keine Ausnahmen" und der Forderung nach
einem deklarativen Syntax, der den Inhalt eines Ausdrucks deutlicher sichtbar macht.
Die verbliebenen Namensr�ume k�nnen eindeutig an der Sigil unterschieden werden.
Oder einfacher: $wunder, @wunder und %wunder sind drei verschiedene Variablen.

Datentyp Code

Der vierte Namensraum ohne Sigil, ist der der Subroutinen. Und wie bei Hashes und
Arrays, k�nnen Referenzen auf Routinen ebenfalls in Skalaren gespeichert werden.

Perl 6:
my $coderef = sub { say "Moin #perl" }

Die besitzen dann den Datentyp "Code". (Das fehlende Semikolon ist kein Fehler.
Perl 6 verlangt nur dann ein solches, wenn mehrere derartiger Deklarationen ohne
den Befehl C<sub> in eine Zeile schreibt. Als Eselsbr�cke: ein "}" am Zeilenende
impliziert ein Semikolon.) Das C<sub> k�nnte man also auch weglassen, was nichts
am Datentyp und an der Benutzung der Variable �ndert.

Perl 6:
my $coderef = { say "Moin #perl" }
# dito, ebenfalls noch m�glich
my $cr = \{ say "Moin #perl" }
$cr.isa(Code) # ergibt Bool::True
$coderef(); # f�hrt den Block aus

Trotzdem sind die Unterschiede zwischen einer "sub" und einem Block so zahlreich,
da� man damit viele Seiten f�llen kann, sie alle aufzuz�hlen. Deshalb wird diese
Folge auch eher Bl�cke behandeln und erst die n�chste die Sonderform "Subroutine".
Einfache Bl�cke besitzen n�mlich nur Grundf�higkeiten und Befehle wie C<while>,
C<if>, C<package> und C<sub> f�gen dem weitere Funktionalit�t hinzu, weswegen sie
im Perl 6-Jargon Blockmodifikatoren genannt werden. Da diese Modifikatoren "builtins"
und keine Routinen sind, kann man sich jetzt nicht nur die runden Klammern sparen.
Es wird empfohlen auf sie zu verzichten. Und wenn nicht anders m�glich, sollte man
zumindest darauf achten, zwischen Modifikator und den runden Klammern Leerzeichen
zu lassen, es sei eine C<sub> namens C<if> m�chte angesprochen sein.

Perl 6:
if $a > 6 { say "Zu alt f�r den Kindergarten" }
if($a > 6) { ... } # Error

Doch beginnen wir mit einem nackten Block.

Closure

Bl�cke sind in Perl 6 alles, was von geschweiften Klammern umschlossen ist, soweit
nicht darin ein C<=>> oder C<pair> steht, oder die voranstehenden Operatoren C<%>
oder C<hash> eine Hashreferenz erzwingen. Sie teilen Code in logische Einheiten.
Dadurch werden die Quellen �bersichtlicher und verst�ndlicher. Es erlaubt aber
auch Variablen einem Block zuzuordnen. Das hat den gro�en Vorteil, da� man damit
heimt�ckische �berschneidungen mit gleichnamigen Variablen anderer Programmteile
ausschlie�en kann. Au�erdem spart es Arbeitsspeicher, wenn die Lebensdauer einer
Variable auf den Block begrenzt wird, in dem ihr Inhalt gebraucht wird.

Der erste Versuch in die Richtung war der Befehl C<local>, der bereits vor Perl 5
eingef�hrt wurde. Doch der �berlagert eine eventuell exisierende, gleichnamige
Variable tempor�r, bis die Ausf�hrung des aktuellen Blocks beendet ist. Deswegen
wurde die Anweisung in C<temp> umbenannt. Eine echte Bindung zwischen Variable und
Block erzeugt C<my>, welches Perl 5 brachte. Seit dem wird eindringlich empfohlen
C<my> anstatt C<local> zu verwenden. Wenn n�mlich aus einem Block (in dem eine
C<local>-Variable definiert wurde) eine Routine aufgerufen wird, �berschreibt die
"lokale" Variable dort gleichnamige Br�der. Da das selten den Erwartungen entspricht,
sollte man es mit C<my> oder C<state> verhindern. Eine so erzeugte, lexikalisch
lokale Variable w�re innerhalb der Subroutine unbekannt und wird nur eingeblendet,
w�hrend ein Befehl des betreffenden Blocks ausgef�hrt wird. Einziger Unterschied
zwischen beiden Befehlen: C<my> initialisiert die Variable nach jedem Neustart des
Blocks von neuem mit dem Anfangswert, wohingegen C<state> da� nur beim ersten Mal
tut und sich danach den Inhalt bis zum n�chsten Blockaufruf merkt. Dieses Verhalten
von C<state>-Variablen nennt man in der Informatik "Closure" und ist seit Jahren
Bestandteil funktionaler Programmierung. Es lie� sich auch mit einem zus�tzlichen,
umschlie�enden Block und C<my> simulieren, was aber umst�ndlich und fehleranf�llig
war. F�r einfache Closures wurde deshalb der C<state>-Befehl von Perl 6 nach 5.10
zur�ckportiert.

Einfache Ausf�hrung mit R�ckhand

In Bl�cken stehen meist mehrere Befehle, von denen der zuletzt ausgef�hrte den
R�ckgabewert des Blocks angibt. Um ihn ihn einer Variable zuzuweisen, mu� der
Befehl C<do> verwendet werden, auch wenn nackte Bl�cke immer ausgef�hrt werden,
solang sie keine Parameter an eine Routine sind. (wie bei map, sort etc.)

Perl 6:
my $zahl = do { rette_regenwald(); gl�ckszahl() }
# oder l�nger :
my $coderef = { rette_regenwald(); gl�ckszahl() }
my $zahl = $coderef();

Auch auf einzelne Befehle, die nicht von geschweiften Klammern umgeben sind, kann
C<do> angewendet werden, um sie als Ausdruck zu evaluieren. Daher ist auch diese
umst�ndliche Umschreibung des tern�ren Operators m�glich.

Perl 6:
$x = do if $a { $b } else { $c };
$x = $a ?? $b :: $c; # k�rzer

Da C<do> einen Block immer genau einmal ausf�hren l��t, werden solche Abschnitte
jetzt auch "do once loop" genannt. Um mit dieser einfachen Regel nicht zu brechen,
wurden Schleifenkonstrukte wie C<do { ... } while ()> in C<repeat { ... } while ()>
umbenannt. Auch alle weiteren Verwendungsm�glichkeiten von C<do> die Perl 5 kennt,
wurden gestrichen. Daf�r f�hrte Larry mit C<gather> eine Variante von C<do> ein,
die einem Block erlaubt eine Liste zur�ckzugeben. Die einzelnen Werte werden mit
dem Befehl C<take> einzeln oder in Gruppen ausgew�hlt.

Perl 6:
# enth�lt: 'Gauguin', 'Cezanne'
my @maler = gather {
my $r = take 'Gauguin';
# $r enth�lt 'Gauguin'
take 'Cezanne' if $r;
}
# enth�lt: 1,10,2,20
my @x = gather for 1..2 {
take $, $ * 10;
}

In Kombination mit Schleifen und bedingten Anweisungen entfaltet C<gather/take>
erst seine volle M�chtigkeit. Die Beispiele zeigen auch wie Blockmodifikatoren
ohne weitere Klammern kombiniert werden k�nnen, was eine Konsequenz der bereits
vorgestellten Regeln ist. Auch bei nachgestellten Konstrukten kann damit manche
Zeilen vereinfacht werden.

Perl 5:
{ print if $_ % 2 } for 0..10;

Perl 6:
.print if $_ % 2 for ^11;

Soll in Perl 6 ein Befehl (als Methode) auf $_ angewendet werden, sollte er mit
einem Punkt beginnen. Die genauen Hintergr�nde dieser Designentscheidung wurden
in der ersten Folge erl�utert. Doch zur�ck zu den R�ckgabewerten. So wie C<take>
sie f�r den umgebenden C<gather>-Block bestimmt, gibt es auch einen Befehl f�r
den skalaren R�ckgabewert, der gleichzeitig die Ausf�hrung des Blocks abbricht.
Dieser Befehl hei�t zur allgemeinen �berraschung nicht C<return>. C<return> ist
Subroutinen und artverwandten Funktionseinheiten vorbehalten, aus Gr�nden, die
in der n�chsten Folge genau beschrieben werden. Das schlichte Verlassen des
umschlie�enden Blocks wird von einem C<leave> ausgef�hrt. Soll ein bestimmter
Block beendet werden, so mu� dessen Anfang durch ein "Label" (LABELNAME:)
markiert sein, um mit C<LABELNAME.leave> aus ihm hinauszutreten. Daraus folgt
ebenfalls, da� Perl 6 die mittelalterlichen Freuden extensiver C<goto>-Benutzung
keineswegs einschr�nkt. Selbst ein fortraneskes "computed goto" kann unver�ndert
(wie in Perl 5) geschrieben werden.

Der mit C<leave> definierte R�ckgabewert kann aber noch mehr, als in eine Variable
zugwiesen zu werden. Er kann auch die Ausf�hrung von Bl�cken steuern, die mit
Auswahloperatoren verkn�pft sind.

Perl 6:
tu_was() && das_auch();
# ist andere Schreibweise f�r:
{ tuwas() } && { das_auch() };
# ist andere Schreibweise f�r:
{ tuwas() } and { das_auch() };

Doch C<&&>, C<||> und C<^^> wurden schon in Folge 2 behandelt und f�r die Ops
macht es keinen Unterschied ob sie die Ergebnisse von einzelnen Befehlen oder
ganzen Bl�cken verkn�pfen. Wirklich neu und speziell nur f�r Bl�cke sind hingegegen
C<andthen> und C<orelse>. Grundlegend entsprechen sie den Befehlen C<and> und C<or>.
Beendet der linke Block erfolgreich, l��t C<andthen> ebenfalls den rechten
ausf�hren. Allerdings, um die Kontextvariable C<$_> weiterhin benutzen zu k�nnen.
Sie wird in diesem Sonderfall sozusagen "Closure" zweier Bl�cke. C<orelse> eignet
sich vor allem zur Fehlerbehandlung. Ist der linke R�ckgabewert nicht positiv,
startet C<orelse> den rechten Block, in dem die Fehlermeldung (Sondervariable $!)
weiterhin bekannt ist.

Bedingte Ausf�hrung ist einfach

In der Regel werden jedoch bedingte Anweisungen mit den vertrauten Schl��elw�rtern
C<if>, C<elsif>, C<else> und C<unless> formuliert. Letzeres ist zwar eine Eigenheit
von Perl, die nicht mehr mit C<elsif> und C<else> kombiniert werden darf, aber die
Funktionsweise dieser 4 Befehle sollte keiner weiteren Erkl�rung bed�rfen.
Auch C<given>, C<when> und C<default> wurden mit ihrer Einf�rung zur Version
5.10 gen�gend vorgestellt. Vergessen wurde dabei manchmal lediglich, da� C<given> und
C<when> sich auch in anderen Zusammenh�ngen benutzen lassen. C<given> eignet sich
hervorragend umst�ndliche Ausdr�cke zu vereinfachen wie folgende:

Perl 6:
$tiefer.objekt.namensraum.var1 =
$tiefer.objekt.namensraum.var2 +
$tiefer.objekt.namensraum.var3;
# oder :
given $tiefer.objekt.namensraum
{ $.var1 = $.var2 + $_.var3 }

Da C<given> ebenso wie C<for> (es gibt kein C<foreach> mehr) die Kontextvariable
setzt, k�nnen C<when>-Klauseln auch in C<for>-Schleifen verwendet werden.

Perl 6:
for @beine {
print "Ist $_ "
when 1 { say "�berhaupt ein Tier?" }
when 6|8|10 { say "ein Insekt?" }
when > 20 { say "eine Raupe?" }
default { say "ein Zweibein"}
}

C<default> ist nur ein Alias auf C<when *> (oder $_ ~~ Whatever) und im Gegensatz
zu einem "C-switch" entfüllt auch das notorische C<break>, da ein implizites
C<break> jede C<when>-Klausel beendet. Wer mag kann aber auch jederzeit mit C<break>
die Klausel und den umgebenden "contextualizer"-Block manuell verlassen. Wenn nur
zur n�chsten Klausel gesprungen werden soll, dann ist C<continue> das Mittel der Wahl.
Noch weitere besondere Sprungbefehle gibt es f�r Schleifen.

Sch�ne Schleifen

Auch hier wurden die alten Standarts kaum anger�hrt. C<while> und C<until> blieben
unver�ndert, lediglich ein C<repeat { ... } while $a < 3;> ist gew�hnungsbed�rftig.
Ansonst wird der Ausdruck nach C<while> und C<until> (ebenso wie bei C<if> und C<unless>)
in den boolschen Skalarkontext evaluiert. Selbstverst�ndlich wird dann bei einem
Ergebnis von Bool::True (beziehungsweise Boole::False) der Block ausgef�hrt. <for>
ist jetzt ein reiner Array-Iterator und evaluiert entsprechend in den "lazy list"-Kontext.
Genau deshalb wird die zeilenweise Abarbeitung einer Datei jetzt so geschrieben:

Perl 6:
my $fh = open "aufsatz.txt";
for =$fh {
...

W�rde jemand C<while> anstatt C<for> nehmen, so lieferte C<=$fh> im Skalarkontext den
gesamten Dateiinhalt auf einmal ab. Bis dahin ist alles logisch, doch was geschah mit
der klassischen "C-Stil"-for-Schleife. Ihr Ausdruck wird eindeutig in den void-Kontext
evaluiert und deshalb bekam sie ein eigenes Schlüsslwort. Inhaltlich unterschiedliches
soll auch optisch unterscheidbar sein. Deswegen heißt die Allzweckschleife nun "Schleife"
(C<loop>). Da der leere Kontext immer das Selbe Ergebnis liefert, ist auch C<loop {...}>
(ein Synonym für C<loop (;;) {...}>) eine nettere Schreibweise für C<while 1 {...}>, daß
weiterhin möglich ist. Eine weitere gute Nachricht: die Sprungbefehle C<last> (verlasse
die Schleife), C<redo> (wiederhole den Durchgang) und C<next> (zur nächsten Iteration)
funktionieren jetzt einwandfrei. Bei C<do {...} while ();> hat hier Perl 5 immer noch
Probleme, denn das sind nachträglich eingeführte Konstrukte und keine echten Schleifen.
Wie C<leave> können auch diese Sprungbefehle mit Labelmarken wie z.B. C<LABEL.next;>
oder C<next LABEL;> kombiniert werden.

Blockparameter

Im letzten Beispiel fehlte noch ein entscheidendes Detail. F�r C<for>-Schleifen wird
oft eine lokale Laufvariable definiert:

Perl 5:
for my $i (1..10) { ...

Weil hier das C<my> nicht innerhalb des Blockes steht, f�r da� es seine G�ltigkeit
besitzt, w�rde das gegen die klaren Regeln in Perl 6 versto�en. Deshalb gibt es daf�r
nun einen besonderen Syntax der es gleichzeitig zul��t mehrere Parameter an einen
Block zu �bergeben. Da der Syntax symbolisieren soll, da� hier schnell ein paar Werte
in den Block "hineingeworfen" werden, nennt sich diese Formulierung "pointy block".
Sie erlaubt elegante L�sungen, f�r die bisher wesentlich kompliziertere Formulierungen
notwendig waren.

Perl 6:
for 1..10 > $i { ...
for %h.kv
> $k, $v { ...
for @a Z @b Z @c > $a, $b, $c { ...
while berechne()
> $wert { ...

Auch wenn C<while> in den boolschen Kontext evaluiert, bekommt C<$wert> den Betrag
den C<berechne()> liefert. Wie beschrieben sind diese Variablen Parameter und nicht
lexikalisch lokal und k�nnen daher auch nicht innerhalb des Blocks ver�ndert werden.
Braucht man jedoch unbedingt ver�nderbare Laufvariablen, so mu� dies mit einem leicht
ge�nderten Syntax gekennzeichnet sein.

Perl 6:
for 1..10 <-> $i { ...

Wenn kein Variablennamen angegeben w�re, landen die Inhalte nat�rlich in $_ oder @.
Nun ist @2 nicht immer der sch�nste Variablennamen und verwirrt manch einen Neuling.
F�r solche F�lle erfand Larry die automatisch benannten Parameter die auch einen
weiteren Sonderfall in Perl 5 mit einer allgemeinen Regel abschaffen. Damit ist der
C<sort>-Befehl gemeint, in dessen Block die einmaligen Sondervariablen $a und $b
bekannt sind, welche jetzt C<$^a> und C<$^b> geschrieben werden. Die Twigil (sekund�re
Sigil) "^" kennzeichnet die Platzhalter-Variablen. Diese d�rfen benutzt werden,
ohne ihre Namen zu deklarieren. Man mu� nur darauf achten, da� alphabetisch sortiert,
ihre Namen der Reihenfolge der Parameter entsprechen, in der sie dem Block �bergeben
wurden.

Perl 6:
for 1..10 { say $^i ...
for 1..10 { say $^cc ...
$coderef1 = { say $^a, $^b };
$coderef2 = { say $^z, $^zz };
$coderef1('a','d'); # sagt ade
$coderef2('a','d'); # dito

Mehr dazu in Teil 5, wenn in Subroutinen die hohe Schule der Parameter�bergabe
zelebriert wird.


Previous Chapter | Overview | Next Chapter