<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0" xmlns:blogChannel="http://backend.userland.com/blogChannelModule">

<channel>
<title><![CDATA[Perl 6: Perl 6 Tutorial Part 5]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_5</link>
<description></description>
<pubDate>Fri, 06 Aug 2010 23:53:55 -0000</pubDate>
<webMaster>synedra@gmail.com</webMaster>
<generator>Socialtext Workspace v2.14.7.2</generator>

<item>
<title><![CDATA[Perl 6 Tutorial Part 5]]></title>
<link>http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_5</link>
<description><![CDATA[<div class="wiki">
<div class="nlw_phrase"><table class='toc'><tr><td><div class="wiki">
<h3 id="contents">Contents: []</h3>
<ul>
<li><span class="nlw_phrase"><a title="section link" href="#captures_und_subroutinen">Captures und Subroutinen</a><!-- wiki: {link: [] Captures und Subroutinen} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#geforderte_parameter">Geforderte Parameter</a><!-- wiki: {link: [] Geforderte Parameter} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#bla_bla_bla">Bla Bla Bla</a><!-- wiki: {link: [] Bla Bla Bla} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#optionale_parameter">Optionale Parameter</a><!-- wiki: {link: [] Optionale Parameter} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#schl_C3_BCrfende_parameter">Schlürfende Parameter</a><!-- wiki: {link: [] Schlürfende Parameter} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#benannte_parameter">Benannte Parameter</a><!-- wiki: {link: [] Benannte Parameter} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#was_zum_sind_capture">Was zum $@%&amp; sind Capture?</a><!-- wiki: {link: [] Was zum $@%& sind Capture?} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#multi_sub_s">Multi Sub's</a><!-- wiki: {link: [] Multi Sub's} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#parameter_traits">Parameter Traits</a><!-- wiki: {link: [] Parameter Traits} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#eingewickelte_routinen">Eingewickelte Routinen</a><!-- wiki: {link: [] Eingewickelte Routinen} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#r_C3_BCckgabekontext">Rückgabekontext</a><!-- wiki: {link: [] Rückgabekontext} --></span></li>
<li><span class="nlw_phrase"><a title="section link" href="#module_und_scope">Module und Scope</a><!-- wiki: {link: [] Module und Scope} --></span></li>
</ul>
</div>
</td></tr></table><!-- wiki: {toc: } --></div><br /><br /><h3 id="captures_und_subroutinen">Captures und Subroutinen</h3>
<p>
Willkommen zum fünften Teil dieses ausführlichen Perl 6-Tutorials, der sich nur<br />
mit dem kleinen &quot;sub&quot;-Befehl beschäftigen wird und einige Dingen die dazu gehören.<br />
Subroutinen oder Funktionen, die in Perl 6 immernoch mit C&lt;sub&gt; deklariert werden,<br />
gehören zu den wichtigsten und grundlegendsten Techniken der Programmierkunst.<br />
Es sind Teilprogramme die mit einem möglichst aussagekräftigen Namen aufgerufen<br />
werden. Meist werden ihnen Werte übergeben und oft liefern sie auch ein Ergebnis<br />
zurück. Jeder der schon etwas Perl kennt, hat bereits Ähnliches geschrieben wie<br />
folgende Funktion, welche die Länge der Hypotenuse berechnet.</p>
<p>
	sub hypotenuse {<br />
		my ($a, $b) = @_;<br />
		sqrt( $a**2 + $b**2 );<br />
	}</p>
<p>
Und die gute Nachricht für Lernfaule lautet: Dies ist vollständig gültiges Perl 6.<br />
Menschen die jedoch gerade von C oder Java zu Perl wechseln, hätten die Subroutine<br />
wohl so geschrieben:</p>
<p>
	sub hypotenuse ($a, $b) {<br />
		return sqrt( $a*$a + $b*$b );<br />
	}</p>
<p>
Und die gute Nachricht für diese Neulinge lautet: Dies ist ebenfalls vollständig<br />
gültiges Perl 6. Die zweite Lösung liegt näher an dem was die meisten anderen <br />
Sprachen da draußen betreiben (entspricht häufig den Lesegewohnheiten) und sie<br />
spart mühevolle Fingerbewegungen (ebenfalls ein Indikator ob etwas perlish ist).<br />
Aber was genau wurde geändert? Folgen dem C&lt;sub&gt;-Namen runde Klammern, definiert<br />
das eine Signatur (Liste der Parameter) und keine Prototypen mehr wie in Perl 5.<br />
Diese Parameter (auch C&lt;@&gt;) sind keine lokalen Variablen und (wenn vorher nicht<br />
anders deklariert) schreibgeschützt. Folgt keine Signatur, landen Parameter in<br />
C&lt;@&gt;, wie aus Perl 5 gewohnt. TIMTOWTDI.</p>
<h3 id="geforderte_parameter">Geforderte Parameter</h3>
<p>
Signaturen helfen jedoch nicht nur Neulingen, sondern nehmen Jedem Arbeit ab. <br />
Zum Beispiel kann C&lt;sub hypotenuse&gt; nur dann sinnvolle Ergebnisse erzielen, wenn<br />
sie 2 Parameter bekommt. Im alten System der Parameterübergabe wäre es aufwendig<br />
dies einzufordern. In Perl 6 braucht der Programmierer dafür gar nichts zu tun, <br />
denn würde man die zweite Routine mit C&lt;hypotenuse(5)&gt; oder C&lt;hypotenuse(2,3,4)&gt;<br />
aufrufen, gäb es eine dicke Fehlermeldung zur Kompilierungszeit. Wäre die C&lt;sub&gt;<br />
wie im ersten Beispiel implementiert, würde der Kompiler lautlos schnurren wie<br />
ein Kätzchen, auch wenn die Ergebnisse der Funktion nicht immer brauchbar wären.<br />
Doch wenn schon die Parameter prüfen, dann auch auf den Datentyp. C&lt;Num&gt; ist ein<br />
nativer Datentypen für Skalare und entspricht dem Zahlenbereich rationaler Zahlen.</p>
<p>
	sub hypotenuse (Num $a, Num $b) {<br />
		return sqrt( $a*$a + $b*$b );<br />
	}</p>
<p>
Der Vorteil einer solchen Prüfung: die Fehlermeldung kommt, wenn Unbeabsichtigtes<br />
passiert (hier bei nichtnumerischen Längenangaben), nicht erst Zeilen später,<br />
wenn ein Folgebefehl versagt. Somit sind Ursachen wesentlich leichter auffindbar.<br />
Und um konsequent zu sein sollte die C&lt;sub hypotenuse&gt; nur Zahlen größer als 0<br />
zulassen, da sie mit physischen Längen rechnet. Dazu definieren wir den eigenen<br />
Datentyp C&lt;Num+&gt; (analog zu Q+) als Untermenge von C&lt;Num&gt; wie folgend:</p>
<p>
	subset Num+ of Num where { $_ &gt; 0 };</p>
<p>
Perfekt wäre es, wenn auch der Typ des Rückgabewertes festgelegt werden könnte.<br />
Das wirkt in diesem Beispiel vielleicht etwas übertrieben, aber Programme werden<br />
so zuverlässiger. Diese Art der Programmierung, bei der der Compiler die Anzahl,<br />
und Typen der Ein- und Ausgabe einer Routine prüft, wird &quot;Design by Contract&quot;<br />
genannt und wurde zuerst durch die Sprache Eiffel bekannt. Da Perl 6 Motto heißt <br />
&quot;All your Paradigm's belong to us&quot; heisst, ist das beschriebene auch hier möglich:</p>
<p>
	Num+ sub hypotenuse (Num+ $a, Num+ $b) { ... }<br />
	sub hypotenuse (Num+ $a, Num+ $b --&gt; Num+) { ... }</p>
<h3 id="bla_bla_bla">Bla Bla Bla</h3>
<p>
Die &quot;...&quot; in den letzten Beispielen waren nicht nur Dekoration die andeutet,<br />
daß an dieser Stelle der eigentliche Code später eingefügt wird. Auch der Perl 6<br />
versteht es in dem Sinne. Der Interpreter geht davon aus, daß der Programmierer<br />
nicht ohne Grund beginnt eine Subroutine zu schreiben und möchte ihm mit einem <br />
freundlichen Kompilererror daran erinnern, daß im Falle:</p>
<p>
	sub hypotenuse; # oder<br />
	sub hypotenuse { }</p>
<p>
etwas fehlt. Der geschickte Softwarearchitekt kann aber mit dem Operator namens<br />
&quot;yadayadayada&quot; (zu deutsch bla bla bla) dem Interpreter mitteilen, daß er später<br />
die Routine schreiben wird. Je nachdem ob er möchte das die jetzige Routine ein<br />
fail, eine Warnung (C&lt;warn&gt;), oder einen Error (C&lt;die&gt;) liefert, kann er die<br />
Schreibweisen C&lt;...&gt;, C&lt;???&gt; oder C&lt;!!!&gt; verwenden. Doch kehren wir zurück zum<br />
ersten Beispiel.</p>
<h3 id="optionale_parameter">Optionale Parameter</h3>
<p>
Manchmal braucht es aber Routinen, die je Situation unterschiedlich viele Parameter<br />
bekommen. Wie deklarier ich das in der Signatur, ohne daß sich der Interpreter<br />
beschwert? In dem ich den Paramtern ein Fragezeichen anhängt und sie damit als<br />
optional markiert.</p>
<p>
	sub hypotenuse (Num+ $a, Num+ $b, Str $txt? --&gt; Num+) {<br />
		my $h = sqrt( $a*$a + $b*$b );<br />
		say &quot;$txt $h.&quot; if $txt;<br />
		return $h;<br />
	}</p>
<p>
Man muß nur darauf achten, in der Signatur die optionalen Parameter nach den <br />
Notwendigen zu positionieren, da alle Parameter in der Reihenfolge befüllt werden,<br />
in der sie der Routine übergeben werden. Deshalb sollte auch die Reihenfolge der<br />
optionalen Parameter sorgfältig überdacht werden, um sie von links nach recht von<br />
mehr zu weniger wichtig zu sortieren. Der Befehl C&lt;if $txt&gt; wird auf keinen Fall<br />
Probleme bereiten. Denn auch wenn kein Antwortsatz gewünscht ist und C&lt;$txt&gt; leer<br />
bleibt, wird die Variable auf jeden Fall mit C&lt;undef&gt; initialisiert. Um andere<br />
default-Werte festzulegen könnte man schreiben:</p>
<p>
	Num+ sub hypotenuse (Num+ $a, Num+ $b, Str $txt?) {<br />
		my $h = sqrt( $a*$a + $b*$b );<br />
		$txt //= 'Länge:<br />
		say &quot;$txt $h.&quot;;<br />
		return $h;<br />
	}</p>
<p>
oder</p>
<p>
	Num+ sub hypotenuse (Num+ $a, Num+ $b, Str $txt = 'Länge: ') {<br />
		my $h = sqrt( $a*$a + $b*$b );<br />
		say &quot;$txt $h.&quot;;<br />
		return $h;<br />
	}</p>
<p>
Da optionale Parameter auch an der Zuweisung erkannt werden, darf das Fragezeichen <br />
im letzten Beispiel weggelassen werden. Das Gegenteil des Fragezeichens ist das<br />
Ausrufezeichen (siehe dem Bedingunsoperator C&lt;?? !!&gt;) Deshalb werden notwendige<br />
Parameter mit einem angehängten C&lt;$var!&gt; deklariert, was aber bei positionalen<br />
Parametern nicht notwendig, da default ist.</p>
<h3 id="schl_C3_BCrfende_parameter">Schlürfende Parameter</h3>
<p>
Manchmal ist es aber auch praktisch eine unbekannte Anzahl von Parametern in einem<br />
Array zusammenzufassen. Dies erreicht man durch einen Stern als Präfix:</p>
<p>
	sub summe (*@a) { <a href="http://www.perlfoundation.org/perl6/index.cgi?%2B" title="[click to create page]" class="incipient">+</a> @a }</p>
<p>
Aber auch Hashes und Skalare aller Art dürfen als &quot;slurpy&quot; deklariert werden. Im<br />
folgenden Beispiel implementieren wir Perl's map-Funktionen. Mit dem Unterschied,<br />
daß bei unserem C&lt;map&gt; der anonyme Block an beliebiger Stelle stehen darf und der<br />
der Interpreter anhand der Signatur die Parameter passend zuordnet.</p>
<p>
	sub map (<strong>&amp;code,</strong> @werte) {<br />
		return gather for @werte -&gt; $wert {<br />
			take $code($wert);<br />
		}<br />
	}</p>
<p>
Würde die Sigantur C&lt;(<strong>@werte,</strong> &amp;code)&gt; lauten, müsste der Block immer an letzter<br />
Stelle übergeben werden.</p>
<h3 id="benannte_parameter">Benannte Parameter</h3>
<p>
Wie angedeutet waren alle bisherigen Parameter positional, richten sich also nach<br />
der Reihenfolge im Funktionsaufruf.</p>
<p>
	sub hypotenuse ($a, $b) {<br />
		sqrt( $a*$a + $b*$b );<br />
	}</p>
<p>
Selbst bei einem Aufruf wie C&lt;hypotenuse($b, $a)&gt; würde der Inhalt der Variable<br />
C&lt;$b&gt; in den Parameter C&lt;$a&gt; kopiert werden und analog Variable C&lt;$a&gt; in C&lt;$b&gt;.<br />
Es gibt jedoch sehr gute Gründe Parameter manchmal direkt beim Namen anzusprechen.<br />
Der Quellcode wird nachvollziehbarer und nicht jeder kann sich die Reihenfolge<br />
von 12 Parametern für jede Routine oder Methode merken. Oft ist auch nicht die<br />
Eingabe von jedem Parameter notwendig, aber wie sag ichs dem Computer, daß ich<br />
diemal gerne die Parameter 3, 5 und 12 übergebe. Selbst die bereits vorgestellten<br />
optionalen Parameter waren positional. Aus der Überlegung erschließt sich auch<br />
warum in Perl 6 benannte Parameter per default optional sind. Wie bekannt kann<br />
das angehängte C&lt;!&gt; sie erzwingen. Benannte Parameter erkennt man am Präfix C&lt;:&gt;.<br />
Und sehr zu beachten: sie folgen den positionalen Parametern in der Signatur.</p>
<p>
	sub new(:$parent, :$ID, :$value :@size, :@pos, :@item, $:style)</p>
<p>
Es gab Moment, da wünschte ich mir beim WxPerl-Programmieren Perl 6 wäre schon da<br />
und z.B. die C&lt;new&gt;-Methode einer Combobox hätte eine solche Signatur. Weil beim<br />
erzeugen des Widget sind bei mir nur die Eltern (Platz in der Objekthierarchie)<br />
und der Sytle (Aussehen und Verhalten) wichtig. Die ID lass ich autogenerieren,<br />
Größe und Position bestimmen die Sizer und Textwert und die Item werden bei Bedarf<br />
gesetzt.</p>
<p>
	my $cb = Wx::Combobox.new( parent =&gt; $win, :style($style) );</p>
<p>
So würde mir das gefallen. Zu Demonstrationszwecken enthält das letzte Beispiel<br />
beide Paar-Schreibweisen. Sie wurden bereits in der vorigen Folge erläutert. Nur<br />
ließe sich hier C&lt;:style($style)&gt; auch zu C&lt;:$style&gt; zusammenfassen.</p>
<p>
Hat eine Routine keine Signatur, erhält sie ihre mt Namen zugewiesenen Parameter<br />
aus C&lt;%&gt;, so wie C&lt;@&gt; nur die positionalen Parameter enthält. Verwendet man<br />
Platzhalter-Variablen wie C&lt;$^a&gt; in Routinen ohne Signatur (obwohl die nur für<br />
einfache Blöcke gedacht sind), erscheinen die Werte dieser Variablen nicht mehr<br />
in C&lt;%&gt; oder C&lt;@&gt;.</p>
<p>
Möchte man ein Paar als positionalen Parameter angeben, muß er in runde Klammern<br />
gesetzt werden. Wie nachfolgend zu sehen, kann man die umschließenden Klammern<br />
einer Signatur meist weggelassen werden.</p>
<p>
	# Aufruf mit einem positionalem Argument<br />
	Wx::Combobox.new (:parent&lt;$win&gt;), ;</p>
<p>
Ich weiß auch: Tk und viele andere Module kennen heute bereits benannte Parameter.<br />
Die Übergabe eines anonymen Hashes hat zumindest optische Ähnlichkeiten, Typen <br />
und Anzahl der Geforderten Parameter werden dabei nicht geprüft. In Perl 6 könnte<br />
man aber auch eine Routine mit einem Hash aufrufen. Damit Perl die Paare des Hashs<br />
als Name und Wert benannter Parameter wertet muss der mit einem senkrechten Strich<br />
dereferenziert werden.</p>
<p>
	Wx::Combobox.new( |%default );</p>
<p>
&quot;|&quot; ist keine Sigil für einen Datentyp, so wie ein &quot;&amp;&quot; für Codereferenzen steht,<br />
es dient lediglich zum interpoliert in den Capture-Kontext, vergleichbar mit &quot;@@&quot;,<br />
daß für den bereits behandelten slice- oder auch multislice-Kontext steht.</p>
<h3 id="was_zum_sind_capture">Was zum $@%&amp; sind Capture?</h3>
<p>
Von allen Neuheiten in Perl 6 fordern I&lt;Capture&gt; wohl am stärksten die Fähigkeit<br />
sich neue Nervenverbindungen wachsen zu lassen, denn soweit mir bekannt, gibt es<br />
nichts Vergleichbares in anderen Sprachen. Ein Capture ist ein Datentyp, der einem<br />
Skalar zugewiesen wird und alle Parameter eines Routinenaufrufs speichern kann.<br />
Da Signaturen sowohl positionale als auch benannte Parameter haben können, <br />
erscheinen Capture anfangs als seltsame Hybride aus Array und Hash. Nur anders<br />
als die Letztgenannten kann eine Capture nicht nachträglich verändert werden.<br />
Sie ist &quot;immutable&quot; wie eine Liste. Weil es jetzt keine Referenzen mehr gibt<br />
bekamen Capture den &quot;\&quot; vererbt, der von nun an &quot;capture composer&quot; heißt.</p>
<p>
	my (@a, $b, %c) = <a href="http://www.perlfoundation.org/perl6/index.cgi?1%20..%205" title="[click to create page]" class="incipient">1 .. 5</a>, 6, {'sonnen' =&gt; 'schein'};<br />
	$capture = \(@a, $b, %c);</p>
<p>
Diese Capture enthält keine Referenzen auf die Variablen sondern nur die Inhalte.</p>
<p>
Anstatt zu referenzieren kann man in Perl 6 einen Alias auf eine Variable in der<br />
Symboltabelle erstellen. Dies geht mit einem sehr einfachen Syntax und gänzlich<br />
ohne Typeglobs.</p>
<p>
	$alias := $kathete;<br />
	$kathete = 5;<br />
	say $alias; # ist 5<br />
	# bindet während Kompilierung<br />
	$alias ::= $kathete;</p>
<h3 id="multi_sub_s">Multi Sub's</h3>
<p>
Erinnern wir uns des ersten Beispiels. Wollte man eine Routine schreiben die die<br />
Länge einer beliebigen Seite des rechtwinkligen Dreiecks berechnet, würden die<br />
bisher vorgestellten Mittel nicht ausreichen. Mit benannten Parametern wäre die<br />
richtige Zuordnung der Seiten gesichert, aber nicht die Forderung, daß 2 von 3<br />
gegeben sein müssen. Eine Lösung bestünde darin das Problem aufzuteilen, was Perl<br />
völlig neue Möglichkeiten eröffnet:</p>
<p>
	multi sub pythagoras (:$kathete!, :$kathete!) {<br />
		sqrt(@kathete[0]**2 + @kathete[1]**2);<br />
	}</p>
<p>
	multi sub pythagoras (:$kathete!, :$hypotenuse!) {<br />
		sqrt($hypotenuse**2 - $kathete**2);<br />
	}</p>
<p>
Das Schlüsselwort C&lt;multi&gt; kündigt an, daß es mehrere Routinen gleichen Namens<br />
gibt. Mit einem C&lt;only&gt; könnte ausschließen, das nachträglich noch eine C&lt;multi&gt;<br />
zu einem Namen deklariert wird. Das ist aber meist nicht notwendig, da normale<br />
C&lt;sub&gt; per default &quot;C&lt;only&gt;&quot; sind.</p>
<p>
Wird die Routine mit C&lt;pythagoras( :kathete&lt;3&gt;, :hypotenuse&lt;5&gt; );&gt; aufgerufen,<br />
prüft der Interpreter welche Signatur zu den Parametern passt. Manch einer ahnt<br />
es schon. Auch dafür wird intern wie bei C&lt;gigen/when&gt; der &quot;smartmatch&quot; benutzt.<br />
Es kann auch sehr praktisch sein selbst zu überprüfen ob ein Satz von Parametern<br />
bei einer Routine Erfolg gehabt hätte.</p>
<p>
	$capture ~~ &amp;routine.signature;</p>
<h3 id="parameter_traits">Parameter Traits</h3>
<p>
Alle bisherigen Paramter konnten in der Routine nicht verändert werden, was meist<br />
sinnvoll ist, aber zuweilen unpraktisch. In diesen Fällen können einzelne Parameter<br />
als veränderbar (rw steht für read/write) gekennzeichnet werden, was einer &quot;&lt;-&gt;&quot;<br />
Zuweisung in I&lt;Pointy-Blocks&gt; entspricht.</p>
<p>
	sub incr (*@vars is rw) { $_++ for @vars }</p>
<p>
Der Befehl C&lt;is&gt; definiert I&lt;Traits&gt; (Charakteristiken) von Variablen. Das sind<br />
neben dem Inhalt zusätzliche Werte oder Eigenschaften die zur Kompilierungszeit<br />
Variablen gegeben werden können. Im Gegensatz dazu werden mit C&lt;but&gt; I&lt;Properties&gt;<br />
(zusätzliche Laufzeiteigenschaften) bestimmt. Somit wird der alte Perl 5-Witz<br />
&quot;0 but True&quot; lauffähiger Code.</p>
<p>
Eine andere Möglichkeit veränderbare Parameter zu erhalten ist der Trait C&lt;copy&gt;.<br />
Wie der Name aussagt sind solche Parameter veränderbare Kopien der übermittelten<br />
Variablen.</p>
<h3 id="eingewickelte_routinen">Eingewickelte Routinen</h3>
<p>
Es gibt sogar Situationen da muß man eine Signatur rückwirkend anpassen. Unsere<br />
großartige C&lt;hypotenuse&gt;-C&lt;sub&gt; könnte Teil eine Matematik-Bibliothek sein die<br />
wir benutzen wollen. Sie kann sogar die Hypotenuse berechnen, wenn ein Winkel und<br />
die gegenüberliegende Seitenlänge gegeben ist. Nur leider rechnet sie mit I&lt;gon&gt;<br />
(Neugrad) und unser Programm mit I&lt;Grad&gt; (Altgrad). Die Bibliothek zu verändern<br />
kommt nicht in Frage, da die Patches in jede neue fehlerreduzierte Version der<br />
Bibliothek eingepflegt werden müssten. Zum Glück gibt es auch dafür in Perl 6<br />
eine elegante Lösung.</p>
<p>
	sub hypotenuse($l, $winkel) {...}<br />
	$handle = &amp;hypotenuse.wrap( { callwith( $^l, $^winkel/360*400 ) } );<br />
	# funktioniert einwandfrei<br />
	hypotenuse(2,20);<br />
	&amp;hypotenuse.unwrap($handle);</p>
<p>
Der letzte Befehl hebt die Umhüllung auf und es können selbstverständlich beliebig<br />
viele Umhüllungen stattfinden. Sind irgendwelche andere Vor- und Nachbereitende<br />
Tätigkeiten auszuführen und die Parameter sollen unverändert an die ursprüngliche<br />
Routine weitergereicht werden, kann man statt C&lt;callwith&gt; auch C&lt;callsame&gt; nehmen.<br />
Beide Befehle liefern die Ergebnisse der originalen Routine, die dann noch nach<br />
Wunsch nachbereitet werden können.</p>
<h3 id="r_C3_BCckgabekontext">Rückgabekontext</h3>
<p>
Nachbearbeitungen werden aber oft vermieden, wenn die Routine auf den Kontext<br />
eingeht in dem sie gerufen wird. Das ist meist eine Signatur über alle Variablen,<br />
denen das Ergebnis der Routine zugewiesen wird. Diese Signatur erhält man mit dem<br />
Befel C&lt;caller.want&gt; und man könnte ohne Damian Conways Modul I&lt;Contextual::Return&gt;<br />
schreiben:</p>
<p>
 given caller.want {<br />
 when :($) {...} # Skalarkontext<br />
 when :(*@) {...} # Arraykontext<br />
 when :($ is rw) {...} # Ein lvalue wird erwartet<br />
 when :($,$) {...} # 2 Werte werden erwartet<br />
 ...<br />
 }</p>
<p>
Für all das gibt es auch noch eine andere Schreibweise.</p>
<p>
 if want.item {...} <br />
 elsif want.list {...} <br />
 elsif want.void {...} <br />
 elsif want.rw {...}</p>
<p>
Dieser Kontexte gibt es noch vieler mehr. Auch ist C&lt;.want&gt; bei weitem nicht die<br />
einzigste Methode zur Introspektion, aber ich will hier kein Handbuch schreiben,<br />
sondern nur einige Möglichkeiten andeuten. Eine vollständige Auflistung aller<br />
Details soll das Tutorial in der Wiki unter<br />
<a target="_blank" title="(external link)" href="http://wiki.perl-community.de/bin/view/Wissensbasis/PerlTafel">http://wiki.perl-community.de/bin/view/Wissensbasis/PerlTafel</a> werden. In diesem<br />
Beispiel wäre ein C&lt;want&gt; anstatt C&lt;caller.want&gt; ausreichend gewesen, aber würde<br />
der C&lt;return&gt;-Befehl innerhalb eines Blocks stehen, wären C&lt;caller.want&gt; und<br />
C&lt;context.want&gt; verschieden.</p>
<p>
C&lt;return&gt; verlässt immer die innerste umgebende Routine. Wird lediglich gewünscht<br />
den Block zu verlassen, empfiehlt sich C&lt;leave&gt; zu nehmen. Logischerweise wird nur<br />
der Rückgabewert von C&lt;return&gt; gegen die Signatur der innersten Routine &quot;gematcht&quot;.</p>
<h3 id="module_und_scope">Module und Scope</h3>
<p>
Was wäre Perl ohne Module. Deshalb bietet Perl 6 auch für Modulauthoren etliche<br />
Verbesserungen zur Vorgängerversion. Da aber in diesem Bereich vieles noch nicht<br />
in trockenen Tüchern ist, jetzt nur einige Grundzüge. Mit C&lt;package&gt; werden <br />
weiterhin Namensräume definiert, für Namensräume mit zusätzlichen Eigenschaften<br />
gibt es jetzt C&lt;module&gt;. Der Befehl C&lt;module Name;&gt; besagt, daß für den Rest der<br />
Datei der Namensraum I&lt;Name&gt; gilt. Für mehrere Module in einer Datei schreibe man<br />
C&lt;module Name{ ... }&gt;. So können Namensräume auch verschachtelt werden und mit<br />
C&lt;my module Name { ... }&gt; Module sogar als lexikalisch lokal bestimmt werden.<br />
Analog dazu dürfen auch Subroutinen jetzt mit C&lt;my&gt; lokal sein. Standartmäßig<br />
entspricht aber weiterhin ein C&lt;sub routine {...}&gt; einem C&lt;our sub routine {...}&gt;.</p>
<p>
Eine der Hauptfähigkeiten von Modulen ist das Exportieren von Routinen. Dazu<br />
benötigt man kein C&lt;use Exporter;&gt; mehr, sondern markiert die entsprechenden<br />
Routinen mit einer I&lt;Trait&gt; als C&lt;is export&gt;. C&lt;sub&gt;-Traits haben ihre Position<br />
nach der Signatur. Module werden wie bekannt mit C&lt;use&gt; oder C&lt;require&gt; geladen,<br />
jedoch wurden auch diese Befehle wesentlich mächtiger um einige Probleme zu lösen<br />
die ein wachsendes CPAN mit sich bringt.</p>
<p>
 use Dog:&lt;1.2.1&gt;;</p>
<p>
So fordert man z.B. eine spezielle Version an. Noch genauer wäre:</p>
<p>
 # bitte keine Version 1.2.7<br />
	use Dog:ver(1.2.1..^1.2.7);</p>
<p>
Auch ein optionaler Mechanismus zur Authentifizieren von Autoren ist im Syntax<br />
vorgesehen, jedoch noch nicht voll ausgereift.</p>
<p>
Namensräume mit weitaus mehr Eigenschaften werden mit C&lt;class&gt; erzeugt. Die OOP<br />
wird aber Stoff der nächsten Folge sein.</p>
<hr />
<p>
<a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_4" title="(34 months)  toc Still operators left Nach Operatoren f r Skalare und Operatoren f r Arrays ist sicher Operatore...">Previous Chapter<!-- wiki-renamed-link Perl 6 Tutorial Part 4 --></a> | <a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial" title="(38 months) This tutorial was written for foo Perl magazine http perl-magazin.de and was published from winter 2...">Overview<!-- wiki-renamed-link Perl 6 Tutorial --></a> | <a href="http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_6" title="(34 months)  toc Objects and Roles Willkommen und hereinspaziert mein Damen und Herren. Hier erleben sie Mensche...">Next Chapter<!-- wiki-renamed-link Perl 6 Tutorial Part 6 --></a></p>
</div>
]]></description>
<author>Herbert Breunung</author>
<guid isPermaLink="true">http://www.perlfoundation.org/perl6/index.cgi?perl_6_tutorial_part_5</guid>
<pubDate>Fri, 06 Aug 2010 23:53:55 -0000</pubDate>
</item>

</channel>
</rss>