Perl 6
Perl 6 Variable Tablet: Revision 20

Overview - Chapter: 0:Intr, 1:Hist, 2:Design, 3:Var, 4:Op, 5:IO, 6:{}, 7:Sub, 8:OOP, 9:Rx - Appendices: A:Index, B:Tables, C:Best of, D:Delta, E:Links




Allison Randal: The most basic building blocks of a programming language are its nouns, the chunks of data that get sucked in, pushed around, altered in various ways, and spat out to some new location.

Primary Types

Perl 6 (as Perl 5) knows 3 basic types of variables, each with an own namespace: Scalars (single values), Arrays (ordered lists) and Hashes (2 column - unordered table with ID and value pairs). They still begin with $ (similar to S), @ (like an a) and % (kv pair), but now in any context, always (invariant), even if you just want a slice of them. $, @ and % can also be used also as an operator that enforces that context.

Special variable namespaces of Perl 5 (often marked with special syntax) like tokens (__PACKAGE__), formats and file or dir handle are now regular (mostly scalar) variables.

Because variables are (as anything in Perl 6) objects, they have methods. In fact, any operator, including those brackets you get array and hash slices with, is just a method of that variable object with a fancy name.

Scalar

This type is known as a storage room for one value, but it's more like a reference that can point to anything: to values of any data type, to code, to another reference, to objects or to a set of values like a pairs, a junction , an array or hash.

$text = "Welcome all!";
$CHAPTER = 3;
$pi = 3.1415926;
$float = 6.02e23;
$handle = open $file_name;
$obj = Classname.new;
$arrayref = [0,1,1,2,3,5,8,13,21];
$hashref = {'audreyt'=>'pugs', 'pm'=>'pct', 'damian'=>'larrys evil henchman'};
$coderef = sub { do_something_completely_diffenent(@_) };

Unlike Perl 5, references are automatically dereferenced to a fitting context. So you could use these $arrayref and $hashref in same way as an array or hash, making $ the variable highlighter, pretty much like in PHP.

Array

is an ordered lists of scalar variables (same as shown before). If not specified otherwise, it can be changed, prolonged and shorten anytime
They are used in Perl as a list, stack, queue and much more

@primes = 2,3,5,7,11,13,17,19,23 ;  # an array gets filled
@primes = (2,3,5,7,11,13,17,19,23); # same thing, since () just do group
@primes = <2 3 5 7 11 13 17 19 23>; # dito, <> is the new qw()
@primes = 2;                        # array with one element
@primes = [2,3,5,7,11,13,17,19,23]; # array with one element (arrayref)
@primes = {'dan' => 'parrot'};      # array with one element (hashref)

Array Slices

Array Methods

@rray.elems;       # number of elements like in scalar @a
@rray.end;         # number des the last element, equal to @rray.elems-1
@rray.reverse;     # reverse the order of elements
@rray.map;         # 
@rray.grep;        # 
@rray.push;        # 
@rray.pop;         # 

Hash

.pre .pre

Hash Slices

$value = %dev{'key'};    # just give me the value related to that key, like in P5
$value = %dev<key>;
$value = %dev<<$key>>;
@values = %dev{'key1', 'key2'};
@values = %dev<key1 key2>;
@values = %dev<<key1 key2 $key3>>;

%dev\ .{'patrick'};      # "long dot style", because its its an object in truth 
%dev   {'audrey'};       # error, only syntax before will work
%dev\  {'allison'};      # error,
%dev   .<dukeleto>;      # error

Hash Methods

%dev.keys
%dev.values
%dev.kv
%dev.pairs


In fact you can use arrays and hashes from a scalar like an array or hash itself (Perl dereferes automatically). Then a $ marks every variable like in PHP.

Ja ihr habt richtig gesehen, file & dirhandler als auch formate haben keinen eigenen Namespace mehr, denn es sind jetzt Objekte auf die wir ja mit einem Skalar zugreifen. Und die Coderef im Beispiel ist auch überflüssig, weil genau das jetzt der aus REXX übernommene say Befehl macht, der wohl auch in Perl 5.10 eingeführt wird. Selbstverständlich kann man in einem Skalar auch rules, junctions, formate und alles was hier sonst so vorgestellt wird speichern, wie auch Paare (neuer Datentyp):

On a deeper level
There are lot more types without own namespaces (usually stored in a scalar) like pairs or capture. Most of them have a sigil which also works as an operator to that type context. After the sigil ($, @ or %) they can also have a secondary sigil, that signals special namespaces, often used by special variables.

object types

Pair

Paare sind praktisch die Bausteine eines Hashes (weiter unten), den man auch als Array(Liste) von Paaren sehen kann. Ein einzelnes Paar kann man wie folgt definieren.

$pair = 'key' => 'value'; # "=>" is der Paarkonstruktor
$pair = :key('value'); # andere Schreibweise

Scalar Context

Ausser Skalaren gibt es in Perl6 nur noch Arrays, Hashes und Captures, einer Mischung aus beidem. Wenn man sie einem Skalar zuweist, wird dem Skalar eine Referenz (Zeiger) darauf zugewiesen, weil Perl immer versucht das Ergebnis in die erwartete Form (in den Kontext) zu bringen. Obiges Beispiel hätte man also auch so schreiben können:

$arrayref = (0,1,1,2,3,5,8,13,21); # (Fibonacci Reihe), ist nun das selbe wie :
$arrayref = [0,1,1,2,3,5,8,13,21]; # was immernoch das selbe ist wie :
$arrayref = \(0,1,1,2,3,5,8,13,21); # aber:
$zahl = (13); # das bleibt Skalar, weil Klammern dienen nur zum Gruppieren
$arrayref = (13,); # das Komma ist der Array-Operator, oder :
$arrayref = [13]; # wenn es nur ein element haben soll
$pairlistref = ('audrey'=>'pugs', 'leo'=>'parrot', 'damian'=>'larrys evil henchman');
$hashref = {'audrey'=>'pugs', 'leo'=>'parrot'}; # "=>" ist hash konstruktor
$hashref = hash {'audrey', 'pugs', 'leo', 'parrot'};# hash ist wie sub ein keyword
$subref = sub {'audrey', 'pugs', 'leo', 'parrot'}; # ref auf sub die ne liste liefert
$subref = {'audrey', 'pugs', 'leo', 'parrot'}; # das selbe, {} machen immer einen block

$arrayref = 13,;                      # comma is the new array generator
$pairlistref = ('larry'=>'STD', 'ruoso'=>'SMOP', 'flavio'=>'Perlito');
$coderef = {'jnthn', 'pm', 'masak'};  # sub returning a list


Damit ist es möglich in perl 6 wie in php für alles Variablen mit einer $ am Anfang zu benutzen, aber man muß es zum Glück nicht.

Arrays

Beginnen mit @ und sind immer noch dynamische Listen, gefüllt mit Skalaren. Ebenso wie Skalare, erzwingt ein Array links des "=" den Listkontext (wobei wir noch flattening, nonflattening und lazy Listkontexte kennenlernen werden).

@primzahlen = 2,3,5,7,11,13,17,19,23 ; # array wird befüllt
@primzahlen = (2,3,5,7,11,13,17,19,23); # ergebnisgleich, da () gruppieren
@primzahlen = <2 3 5 7 11 13 17 19 23>; # dito, <> ist das neue qw()
@primzahlen = 2; # array mit einem element
@primzahlen = [2,3,5,7,11,13,17,19,23]; # array mit einem element (arrayref)
@primzahlen = {'dan' => 'parrot'}; # array mit einem element (hashref)

Was sich geändert hat ist, das Arrays jetzt IMMER mit @ beginnen selbst wenn ich nur auf einzelne Elemente zugreifen will. Neu ist auch das Arrays Objekte mit eigenen Methoden sind:

Perl5 Perl6

$primzahlen[1]; @primzahlen[1]; # zweites Element
@{$ref->[1][2]{"a"}}[1,2,3]; $ref[1][2]{"a"}[1,2,3]; # Teilarray, kein deref wegen strikter Sigils
@rray; (im skalarkontext) @rray.elems; # Anzahl der Elemente
$#rray; @rray.end; # nummer des letzten Elements (@rray.elems-1)
$rray[-1]; @rray[*-1]; # Inhalt des letzten Elementes
"@rray" "@rray[]" # alle Elemente einfügen

Arraymethoden

Auch gestandene Perl5 Arraybefehle wie reverse, sort usw. werden ebenfalls optional als Arraymethoden aufrufbar.

Arraykontext

Hashes

Erkennt man an der %-Sigil, die nun auch konsistent ist. Wie angedeutet sind Hashes nun Listen anonymer Paare, die ihren eigenen Hashlistkontext erzwingen können.

%perl6leute = ('audrey'=>'pugs', 'leo'=>'parrot', 'damian'=>"larry's evil henchman");
%perl6leute = ('audrey', 'pugs', 'leo', 'parrot', 'damian', "larry's evil henchman"); # geht auch
%perl6leute = ('Flavio' p5=> 'kp6', 'will' p5=>'parrot', 'pmichaud' p5=> 'pct'); # sogar das

Letzte Version ist für Coder die es unbedingt kompatibel haben wollen. Nun gibt es noch mehr Formulierungsmöglichkeiten, per Hashschlüssel zu den einzelnen Werten zu kommen.

%perl6leute{'audrey'}; # ergibt pugs
%perl6leute<audrey>; # kürzere Schreibweise
%perl6leute{"audrey"}; # eval Variante, denn statt text könnte auch Skalar innerhalb () stehen
%perl6leute{$audrey}; # 
%perl6leute<<$audrey>>; # kürzere Schreibweise, geht auch mit Chevron Symbolen aus Unicode ("<<")
%perl6leute<<audrey leo>>; # liefert den array: ('pugs', 'parrot')
%perl6leute\ .{'audrey'}; # Schreibweise: "long dot", denn eigentlich ist es ja ein Objekt
%perl6leute {'audrey'}; # Error, nur vorige Schreibweise gültig
%perl6leute\ {'audrey'}; # Error, 
%perl6leute .<audrey>; # Error

Hashes haben jetzt ebenfalls eigene Methoden, die z.B. wichtig werden, wenn wir damit Arrays füllen wollen.

@leute = %perl6leute.keys; # ('audrey', 'leo', ...)
@aufgaben = %perl6leute.values;# ('pugs', 'parrot', ...)
@flatlist = %perl6leute.kv; # a la perl5 = ('audrey', 'pugs', ...)
@pairlist = %perl6leute.pairs; # (paar1, paar2, )
@pairlist = %perl6leute; # das gleiche, implizit

Capture

Dies ist wohl eine der härtesten Nüsse unter den Perl6 Neuerungen, da sich weder in Perl5 noch in anderen Sprachen vergleichbares findet. Grob gesagt ist eine Capture eine Referenz auf eine Suboutinen-Signatur. Da Parameter nach Position geordnet oder Namen haben können, erscheinen Capture am Anfang als eigenwillige Mischform aus Array und Hash. Da eine Capture normal mit einem $ anfängt, also ein Zeiger einzelner Zeiger auf eine solche Struktur ist, löst sie auch die Perl 5-Referenzen ab. Auch die bereits vorgestellten Referenzen auf Arrays oder Hashes sind in Wirklichkeit Capture, die wissen wie man sich dem Kontext gemäß zu verhalten hat. Im einfachsten Falle sind Syntax und Verhalten einer Referenz auf eine einfache Variable dem von Perl 5 gleich. Dies ist nur ein vereinfachter Sonderfall. Capture können sehr viel mehr, wie die folgenden Beispiele zeigen: (Der senkrechte Strich dereferenziert eine Capture.)

my $cap1 = \$x; # die einfachste Capture
my $args = \($fh: "Hi!"); # ein benannter Parameter mit Inhalt
sub routine (|$args) { ... } # fütter damit eine sub

sekundäre Sigil
Wirklich neu in Perl6 ist auch, daß Variablen nach der primären Sigil ($, % oder @), die den Datentyp angibt, nun auch optional eine sekundäre Sigil (auch Twigil tweak + sigil genannt) haben können die einen speziellen Namensraum oder Variableneigenschaften markiert. Sie sind im einzelnen im Anhang B aufgeführt und erklärt.

Assignment and Binding

Assignment

Wie eben schon gezeigt, können sich Variablen mit dem einfachen Gleichheitszeichen ("=") ihre Inhalte gegenseitig zugeweisen. In deutsch: der Inhalt der rechten wird in die linke Variable kopiert. Dabei ist egal welchen Typ sie haben, solang beide Typen gleich sind:

$kopie = $original; 
@kopien = @originale;
%kopie = %original; 
$kopie2 = $kopie1 = $original; 
@kopien = ($original1, $original2);
(@kA, @kB) = (@orig_A, @orig_B);

Binding

Doch manchmal möchte man, das 2 Variablen immer den Selben Inhalt haben, egal welche von beiden ich grad verändere (beide Variablennamen sind dann Aliase auf die selbe Variable). Perl6 spricht dann von einem Binding das über die interne Symboltabelle geschieht.

$spiegel = \$original; # Perl5 schreibweise, geht immernoch, Originalwert in $$spiegel
$spiegel := $original; # Perl6 binding zwischen 2 Skalaren
$spg2 := $spg1 := $orig; # 2 Spiegel auf eine dritte Variablen
($spg1, $spg2) := ($orig1, $orig2); # man kann auch 2 Variablen auf einmal binden
($spg1, $spg2) := ($orig1); # ERROR, Anzahl muss gleich sein
($s1, @s2 %s3) := ($o1, @o2, %o3); # alle Typen kann man an Variablen gleichen Typs binden
$spiegel ::= $original; # Perl6 binding zur Kompilierungszeit
$spiegel =:= $original; # prüft ob die beiden Variablen aneinander gebunden sind
$spiegel!=:= $original; # negierte Form

Scope

Variablen, denen man bei der ersten Erwähnung ein my voranstellt, sind lexikalische Variablen, weil ihre Lebensdauer auf den akuellen lexikalischen Bereich (aktueller Block) begrenzt ist. Dies gilt nun ohne Ausnahmen. Mit our deklarierte Variablen werden in die Symboltabelle des aktuellen package eingetragen und sind über den Packagenamen auch von ausserhalb zugreifbar. Globale Variablen werden mit einer sekundären Sigil * gekennzeichnet.

my $var;
state
temp
let
our $var;
$*var;

Types

Es ist eine von Perls Stärken, daß Datentypen wie int, char, real u.s.w. alle in Skalare passen und bei Bedarf automatisch konvertiert werden (siehe oben und kontexterzeugende Skalaroperatoren). Dies hilft Programme schnell und sorglos zu schreiben, zu Lasten der Systemressourcen. Deswegen ermöglicht Perl6 jetzt auch Variablen zu typisieren und damit - wo nötig - Speicherverbrauch verringert und Geschwindigkeit erhöht werden kann. Wird z.B. in einem Algorithmus eine Variablen nur als Integer verwendet, kann diese auch zu Begin als Int deklariert werden und der Interpreter kann entsprechend optimieren. Dabei kann der Anfangsbuchstabe des Types groß oder klein geschrieben werde. In der Kleinschreibung wird auf den Typ optimiert, aber Zuweisungen anderer Typen bleiben mit Geschwindigkeitsverlust möglich. Bei Großschreibung werden Typen fixiert, jede typenfremde Operation erzeugt dann eine Fehlermeldung. Eine grosse Platzersparnis können auch packed Arrays sein, denn wenn ich 10.000 Werte speichern will, die alle nicht grösser als 15 werden, kann ich den Array auch als int4 typisieren, also als 4-Bit Integer. Damit spare ich nicht nur den Speicher für die String-Representation aller 10.000 Werte sondern kann auch jetzt 16 Werte speichern, wo vorher nur einer hingepasst hätte. (siehe auch Typentabelle im Anhang B)

my Int $scalar;
my int $scalar;
my Array of Int %hash;
my buf @buffers;
my ref[Array] @ragged2d;

my Dog $spot = Dog.new( );
our Int $pi = 3;
my int @array;
my str @array;
my bit @array;

Properties and Traits

Neu in Perl 6 ist auch, daß Variablen zusätzliche Eigenschaften erhalten können. Diese werden traits genannt, wenn sie mit is zur Startzeit des Programmes (compiletime) definiert werden oder properties wenn sie mit but zur Laufzeit (runtime) verändert werden.

constant $pi = 3.14159;
$true_value = 0 but true;
my @array is dim(2,5,42); # Größe der Dimensionen festlegen

Special Variables

are listed here


Overview - Chapter: 0:Intr, 1:Hist, 2:Design, 3:Var, 4:Op, 5:IO, 6:{}, 7:Sub, 8:OOP, 9:Rx - Appendices: A:Index, B:Tables, C:Best of, D:Delta, E:Links


Upload Files

Click "Browse" to find the file you want to upload. When you click "Upload file" your file will be uploaded and added to the list of attachments for this page.

Maximum file size: 50MB

 
 
 
File Name Author Date Uploaded Size

Save Page As

Enter a meaningful and distinctive title for your page.

Page Title:

Tip: You'll be able to find this page later by using the title you choose.

Page Already Exists

There is already a page named XXX. Would you like to:

Save with a different name:

Save the page with the name "XXX"

Append your text to the bottom of the existing page named: "XXX"

Upload Files

Click "Browse" to find the file you want to upload. When you click "Add file" this file will be added to the list of attachments for this page, and uploaded when you save the page.

 
 
 
Add Tags

Enter a tag and click "Add tag". The tag will be saved when you save the page.

Tag: 

Suggestions: