spacer
    home > webdesign > perl-referenz
spacer
Webdesign Perl-Referenz

 

Perl-Referenzen

Perl allgemein

Ausführung von externem Code mittels do()

Wird die Zahl der Subroutinen in einem Programm immer größer oder verwendet man dieselben (oder ähnliche) Unterprogramme immer wieder in verschiedenen Programmen, so sollte man den Programmcode auf mehrere Dateien verteilen. Es empfiehlt sich, das Hauptprogramm zusammen mit ein paar wichtigen Subroutinen in einer Datei zu speichern (die dann als Perl-Skript ausgeführt wird), und alle anderen Subroutinen (bzw. Klassen bei objekt-orientierter Programmierung) - in logischen Gruppen zusammen gefaßt - in eigenen Dateien abzulegen.

Um nun Programmcode aus einer zusätzlichen Datei in ein Hauptprogramm einzubinden, gibt es in Perl verschiedene Möglichkeiten.

Die einfachste ist die Verwendung der Funktion "do()". Hiermit wird Programmcode aus einer externen Datei so wie er dort abgelegt ist in das aktuelle Programm (also an die Stelle, wo do steht) eingebaut und ausgeführt (so als würde man eval() auf den Dateiinhalt anwenden).

Datei prog.pl:

#!/usr/local/bin/perl -w

print "Erste Zeile des Hauptprogramms\n";
do "funkt.pl";
print "Ende des Hauptprogramms\n";
                  

Datei funkt.pl:

print "Ausgabe aus 'funkt.pl'\n";
                  
Erste Zeile des Hauptprogramms
Ausgabe aus 'funkt.pl'
Ende des Hauptprogramms
                  

Wie man sieht, erwartet do() als Argument einen Dateinamen. Diese Datei wird dann in allen Verzeichnissen gesucht, die im Array @INC aufgelistet sind. Befindet sich die gesuchte Datei in einem Verzeichnis, das nicht standardmäßig zu @INC gehört, so kann der Pfad (vor dem Aufruf von do()) beispielsweise durch

push(@INC,$verzeichnispfad);

hinzugefügt werden.

Ein Nachteil von do() ist die Tatsache, das jedes mal, wenn diese Funktion aufgerufen wird, die entsprechende Datei geöffnet, gelesen und geparst wird, weswegen sich der Einsatz z.B. innerhalb einer oft durchlaufenen Schleife nicht gerade empfiehlt.

Code-Einbindung mit Hilfe von require()

Die Funktion require() bindet im Prinzip genauso wie do() Programmcode aus einer externen Datei ein, allerdings mit dem Unterschied, daß das Einlesen nur einmal geschieht und Perl beim nächsten Aufruf schon "weiß", daß sich der entsprechende Code schon im Speicher befindet und nicht wieder neu geladen werden muss.

Datei prog.pl:

#!/usr/local/bin/perl -w

print "Erste Zeile des Hauptprogramms\n";
require "funkt.pl";
print "Ende des Hauptprogramms\n";
                  

Datei funkt.pl:

print "Ausgabe aus 'funkt.pl'\n";
                  
Erste Zeile des Hauptprogramms
Ausgabe aus 'funkt.pl'
Ende des Hauptprogramms
                  

Ebenso wie do() durchsucht auch require() alle Verzeichnispfade in @INC.

Ein wesentlicher Unterschied zu do() besteht aber darin, daß der Code in der eingebundenen Datei bei der Ausführung eine "wahren" Wert (true) zurückliefern muss. Im obigen Beispiel ist dies relativ offensichtlich, da der Aufruf "print ..." eine wahren Wert ("1") zurückgibt (auch wenn er meist nie verwendet wird). Um sicherzugehen, daß externer Code wirklich zum Schluss true liefert, hat es sich eingebürgert, ans Ende der Datei eine kurze Zeile mit dem Inhalt "1;" anzuhängen - sie bewirkt die Auswertung von "1", was true entspricht und ist der letzte Aufruf der Datei und somit der Rückgabewert an require().

Die Datei funkt.pl aus obigem Beispiel sollte also besser so aussehen:

print "Ausgabe aus 'funkt.pl'\n";

1;
                  

Eine zweite Besonderheit von require(), die bei der Verwendung von sogenannten Modulen ausgenutzt wird, ist die Tatsache, daß falls als Argument ein Name angegeben wird, der nicht einen in Anführungsstrichen stehenden String darstellt, an diesen Namen automatisch die Endung .pm hinzugefügt wird. Somit sind die Aufrufe im folgenden Beispiel völlig äquivalent:

#!/usr/local/bin/perl -w

$dateiname = "extern.pm";
require $dateiname;
require 'extern.pm';
require extern;        # Automatische Ergänzung von .pm
                  

Während die Dateiendung .pl üblicherweise für Skripten/Programme genutzt wird, verwendet man .pm für Dateien, die Perl-Module enthalten.

Verwendung von use()

Noch leistungsfähiger als require() ist die Funktion use(). Von der Funktion her entspricht ein use-Aufruf dem einen von require gefolgt von import. Letztere ist keine von Perl vordefinierte Funktion sondern eine Funktion, die in einem einzubindenden Modul definiert wird und üblicherweise dazu verwendet wird, um Funktionsnamen zu importieren, damit sie dann genauso wie andere Funktionen im Hauptprogramm aufgerufen werden können.

Ein zweiter Unterschied besteht darin, daß use() nicht (wie require()) an der entsprechenden Stelle zur Laufzeit des Hauptprogramms abgearbeitet wird, sondern schon bei der Kompilierung des Programms.

Datei prog.pl:

#!/usr/local/bin/perl -w

print "Erste Zeile des Hauptprogramms\n";
use modul;     # eigentlich "modul.pm"
print "Ende des Hauptprogramms\n";
                  

Datei modul.pm:

print "Ausgabe aus 'modul.pm'\n";

1;
                  
Ausgabe aus 'modul.pm'
Erste Zeile des Hauptprogramms
Ende des Hauptprogramms
                  

An der Reihenfolge der Ausgabe erkennt man schon, daß der Code der Datei modul.pm schon abgearbeitet wird, bevor das eigentliche Hauptprogramm beginnt.

Eine wichtige Konsequenz davon ist, daß man nun nicht mehr durch eine Zeile wie

push(@INC,$verzeichnispfad);

vor dem use-Aufruf im Hautprogramm einen zusätzlichen Suchpfad angeben kann, da use() schon abgearbeitet wird, bevor überhaupt eine Zeile des Hauptprogramms zur Ausführung kommt. Zur Lösung dieses Problems kann man den entsprechenden push-Befehl in einen BEGIN { ... }-Block einbetten, so daß auch diese Funktion zur Kompilierungszeit aufgerufen wird.

Datei prog.pl:

#!/usr/local/bin/perl -w

BEGIN {
  $pfad = 'subdir';
  push(@INC,$pfad);
}
print "Erste Zeile des Hauptprogramms\n";
use modul;
print "Ende des Hauptprogramms\n";
                  

Datei modul.pm im Unterverzeichnis subdir :

print "Ausgabe aus 'modul.pm'\n";

1;
                  

Array

Ein Beispiel für ein zweidimensionales Array ist eine sogenannte Matrix. Dabei handelt es sich zunächst einfach um eine Anordnung von Zahlen (oder Variablen oder Termen oder...) in einem Feld, wobei jeder Eintrag durch zwei Kennziffern (Indizes) bestimmt ist.

Beispiel einer 2x3-Matrix (2 Zeilen, 3 Spalten):

A= SIZE="+4">(
a b c
d e f
SIZE="+4">)

Um eine einzelne Variable zu beschreiben, setzt man Zeile und Spalte als Index an den Namen der Matrix, z.B.:

A = b
1,2

Will man nun ein Perl-Programm schreiben, das mit Matrizen arbeiten soll, muß man sich überlegen, wie man sie geeignet speichert. Da Arrays ein geordnetes eindimensionales (ein Index) Schema darstellen, ließe sich eine Matrix wohl aus der Kombination von Arrays repräsentieren.

Wie es nicht geht

Die einfachste Idee scheint zu sein, die Zeilen jeweils in einzelnen Arrays zu speichern und dann diese Zeilen-Arrays in ein Matrix-Array einzusetzen:

#!/usr/local/bin/perl -w
	

@zeile_1 = ( 'a', 'b', 'c' );
@zeile_2 = ( 'd', 'e', 'f' );


@matrix = ( @zeile_1, @zeile_2 ); 
# 6-elementiges Array !
                  

Obiger Code erzeugt keineswegs eine zweidimensionale Matrix in @matrix. In der letzten Zeile werden nämlich zuerst die beiden Zeilen-Arrays @zeile_1 und @zeile_2 als Listen dargestellt, die dann vor der Zuweisung zu einer 6-elementigen Liste vereinigt werden. Die letzte Zeile des obigen Programms ist also äquivalent zu:

@matrix = (
                            'a', 'b', 'c', 'd', 'e', 'f' ); 

Die Ursache für dieses Verhalten liegt darin begründet, daß Arrays in Perl grundsätzlich nur skalare Größen enthalten, aber keine Arrays oder Hashe (sie werden, wie oben beschrieben, vorher umgewandelt).

Verwendung von Referenzen

Einen Ausweg aus dem Dilemma bieten Referenzen, da sie skalare Variablen sind, aber auf beliebige Datentypen (so auch Arrays) "zeigen" können.

 #!/usr/local/bin/perl -w
	

@zeile_1 = ( 'a', 'b', 'c' );
@zeile_2 = ( 'd', 'e', 'f' );


@matrix = ( \@zeile_1, \@zeile_2 );
                  

Nun enthält das Array @matrix zwei (skalare) Elemente, die ihrerseits jeweils eine Referenz auf ein Zeilen-Array sind.

Wie kann man nun auf die einzelnen Matrixelemente zugreifen ? Die Elemente $matrix[0] und $matrix[1] enthalten jeweils eine Referenz auf ein Array, so daß nach der Dereferenzierung die Zeilen-Arrays zur Verfügung stehen.

An dieser Stelle sei noch einmal darauf hingewiesen, daß in Perl Array-Indizes üblicherweise bei 0 anfangen. Man sollte nicht die Variable $[ auf 1 setzen, um bei 1 mit der Zählung zu beginnen, sondern besser die Elemente oder Zeilen-Arrays gezielt an die Positionen 1,2,... der jeweiligen Arrays schreiben. Der Einfachheit halber wird in den Beispielen auf dieser Seite darauf verzichtet, so daß zu beachten ist, daß von den Matrix-Indizes immer jeweils 1 zu subtrahieren ist, um die Array-Indizes zu erhalten.

Ein ausführliches Beispiel sieht dann so aus:

 #!/usr/local/bin/perl -w
	

@zeile_1 = ( 'a', 'b', 'c' );
@zeile_2 = ( 'd', 'e', 'f' );


@matrix = ( \@zeile_1, \@zeile_2 );


$ref_1 = $matrix[0];
@zeile_1 = @$ref_1;


$ref_2 = $matrix[1];
@zeile_2 = @$ref_2;


print "1) @zeile_1\n";
print "2) @zeile_2\n";
                  

Der Zugriff läßt sich natürlich auch kompakter programmieren:

@matrix = ( \@zeile_1, \@zeile_2 );

print "1) @{$matrix[0]}\n";
print "2) @{$matrix[1]}\n";
                  

Wegen der Präzedenzregeln müssen bei den Dereferenzierungen hier geschweifte Klammern gesetzt werden (ansonsten würde Perl zuerst versuchen, $matrix zu dereferenzieren und erst dann dort das Element mit dem entsprechenden Index suchen).

Mit Hilfe dieses Mechanismus lassen sich auch gezielt einzelne Matrixelemente auslesen und mit Werten besetzen:

#!/usr/local/bin/perl -w

@zeile_1 = ( 'a', 'b', 'c' );
@zeile_2 = ( 'd', 'e', 'f' );
@matrix = ( \@zeile_1, \@zeile_2 );

print "Matrix(1,2) = 
${$matrix[0]}[1] \n";


${$matrix[1]}[2]  = 'x';
print "1) @{$matrix[0]}\n";
print "2) @{$matrix[1]}\n";
                  

Matrix(1,2) = b
1) a b c
2) d e x
                  

Eine alternative Schreibweise für den Zugriff auf ein einzelnes Element bietet der Pfeil-Operator "->"(nicht zu verwechseln mit "=>" als Kommaersatz):

print "Matrix(1,2) = 
$matrix[0]->[1] \n";


$matrix[1]->[2]  = 'x';
                  

Und auch dies läßt sich noch verkürzen, da Perl zwischen zwei aufeinander folgenden Klammern (eckig oder geschweift) automatisch einen Pfeil-Operator setzt. Dadurch läßt sich eine sehr intuitive und übersichtliche Schreibweise erreichen:

 print "Matrix(1,2) = 
$matrix[0][1] \n";


$matrix[1][2]  = 'x';
                  

Anonyme Arrays

Wie der Name schon vermuten läßt, handelt es sich dabei um Arrays, die keinen eigenen Variablennamen besitzen. Die einzige Möglichkeit, auf den Inhalt zuzugreifen, besteht in einer Referenz auf dieses Array. Erzeugen kann man ein solches Array, indem man bei einer Liste eckige anstelle von runden Klammern verwendet. Der Rückgabewert ist dann eine Referenz auf diese Liste.

Beispiel:

 #!/usr/local/bin/perl -w

@array     = ( 10, 20, 30, 40 );     
# normales Array 
$ref_array = 
[  10, 20, 30, 40  ]
;      # anonymes Array

                  

Da ein solches anonymes Array eine Referenz liefert, kann man daraus direkt mehrdimensionale Felder erstellen. Die weiter oben als Beispiel verwendete Matrix ließe sich dann auch so erzeugen:

 #!/usr/local/bin/perl -w

@matrix = ( [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] );
                  

Noch einmal zur Erinnerung: würde man hier runde statt eckige Klammern verwenden, erhielte man ein einfaches 6-elementiges Array in @matrix.

Auf die Matrixeinträge kann hier genauso zugegriffen werden wie weiter oben bei den benannten Arrays beschrieben.

Ein Beispiel, wie man die gesamte Matrix ausgeben kann:

 #!/usr/local/bin/perl -w

@matrix = ( [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] );

foreach $ref_zeile (@matrix) {
    foreach $spalte (@$ref_zeile) { print "$spalte " }
    print "\n";
}
                  

 a b c 
d e f 
                  

Da eine solche zweidimensionale Datenstruktur letztlich auf (eindimensionalen) Arrays beruht, kann man sie mit Hilfe bekannter Funktionen wie push() oder pop() dynamisch verändern. So läßt sich die oben definierte Matrix beliebig bearbeiten:

 #!/usr/local/bin/perl -w

@matrix = ( [ 'a', 'b', 'c' ], [ 'd', 'e', 'f' ] );

pop( @{$matrix[1]} );                 
# 'f' entfernen
 unshift( @{$matrix[0]}, 'M' );       
 # 'M' einfügen

 push(@matrix, [ sort( 'i', 'h', 'g' ) ] );  
# 3.Zeile

 foreach $ref_zeile (@matrix) {
    foreach $spalte (@$ref_zeile) { print "$spalte " }
    print "\n";
}
                  

 M a b c 
d e 
g h i
                  

Wie man sieht, wird auch der (Array-)Rückgabewert einer Funktion (hier: sort()) durch [...] in ein anonymes Array umgewandelt.

Eine Variable, die ein Array in Perl darstellt, ist durch das Zeichen "@" gekennzeichnet. Da skalare Variablen und Arrays unabhängig voneinander verwaltet werden, darf es in einem Programm durchaus eine Zahl $ALF und ein Array @ALF geben.

Arrays sind grundsätzlich eindimensional (Vektoren) und enthalten als Elemente skalare Größen. Wie bei Zeichenketten muss auch bei Arrays keine Speicherplatzreservierung vorgenommen werden und Arrays können im Laufe eines Programms praktisch beliebige Größen annehmen. Versucht man, auf ein nicht definiertes oder gesetztes Element zuzugreifen, so erhält man eine "0" im Zahlenkontext bzw. einen Leerstring "" im Zeichenkettenkontext zurück (intern besitzt die Variable den Wert "undef").

Die Elemente eines Arrays können im wesentlichen auf zwei Arten mit Werten besetzt werden :

  • @vector = (4,6,"ein String",25);

    Hier bekommen die ersten vier Elemente von @vector die entsprechenden Werte.

  • $vector[7] = 42;

    Bei der Zuweisung über einen Index ist hier das Dollar-Zeichen $ zu beachten, da "vector[7]" eine skalare Variable und kein Array darstellt ! Die Indizierung der Arrays beginnt normalerweise bei 0 (Dies kann durch Änderung der reservierten Variablen $[ beeinflußt werden - z.B. $[=1 - , kann aber unter Perl 5 zu Problemen führen, da dort diese Zuweisung nur innerhalb eines Files gilt). In diesem Beispiel müssen übrigens die Inhalte $vector[0] bis $vector[6] überhaupt nicht besetzt werden.

Die Länge eines Arrays kann bestimmt werden, indem man die Array-Variable in einem skalaren Kontext verwendet; den Index des letzten Elements erhält man durch Voranstellen von "$#" vor den Arraynamen.

#!/usr/local/bin/perl -w
		

@vector = (4,6,"ein String",25);
$laenge = @vector;                   
# skalarer Kontext !
print "Laenge = $laenge\n";
print "Letzter Index = $#vector\n";
print "\$vector[1] = $vector[1]\n";


$vector[7] = 42;
$laenge = @vector;
print "Laenge = $laenge\n";
print "Letzter Index = $#vector\n";
                  

Laenge = 4
Letzter Index = 3
$vector[1] = 6
Laenge = 8
Letzter Index = 7
                  

Aus einem Array kann auch ein Ausschnitt ("slice") genommen werden, indem der entprechende Indexbereich angegeben wird.

#!/usr/local/bin/perl -w
		

@vector = (2,4,6,8,10,12);
@slice = @vector;                  
# (2,4,6,8,10,12)
@slice = @vector[2,3,4];           
# (6,8,10)
@slice = @vector[2,4];             
# (6,10)
@slice = @vector[3..5];            
# (8,10,12)
                  

Ein spezielles Array ist @ARGV. Es enthält die Parameter/Optionen, die dem Skript beim Aufruf mit übergeben werden. Beispiel:

#!/usr/local/bin/perl -w
		

foreach $i (@ARGV) { print $i."\n" }              
                  

ACHTUNG : Im Gegenteil zur Programmiersprache C liefert $ARGV[0] den ersten Parameter und nicht den Namen des Programms (Dieser Filename befindet sich in Perl in der Variablen $0) !

Assoziative Arrays

Kennzeichen eines assoziativen Arrays ("hash") ist die Paarung von jeweils zwei Elementen in der Form "Schlüssel-Wert". Gekennzeichnet wird ein assoziatives Array durch ein Prozentzeichen "%" vor dem Variablennamen.

#!/usr/local/bin/perl -w
		
                                                               
%alter = ("Sabine","27","Klaus","35","Ralf","22");
print "$alter{Sabine}\n";
print "$alter{Klaus}\n";
print "$alter{Ralf}\n";
foreach $key (keys(%alter))                  
# foreach
{
   print "$key\n"                  
# (hier ";" nicht unbedingt noetig)
}
                  

27
35
22
Klaus
Sabine
Ralf
                  

Hier wird auf die Werte der Schlüssel in %alter durch $alter{...} zugegriffen (man beachte auch hier das Dollar-Zeichen). Eine Liste aller Schlüssel in einem assoziatien Array erhält man durch die Funktion keys(); analog kann man eine Liste aller Werte durch values() bekommen. Die Reihenfolge der Elemente ist dabei willkürlich und muß keineswegs mit der in der Definition übereinstimmen (obige Ausgabe ergab sich unter MacPerl).

Man kann die Elemente eines assoziativen Arrays mit Hilfe der Funktion each() auch paarweise jeweils in ein zweielementiges Array lesen.

#!/usr/local/bin/perl -w
		
                                                               
%h = ("Auto" => 1,"Haus" => 2,"Baum" => 3);


while(@a = each(%h)) {
  print "$a[0] ($a[1])\n";
}
                  

Haus (2)
Auto (1)
Baum (3)
                  

Die Reihenfolge ist auch hier (scheinbar) willkürlich - sie hängt von der internen Speicherung der Daten ab.

In diesem Beispiel wurde anstelle von Kommata ein Pfeil-Symbol ( "=>") verwendet. Dieses Symbol ist einem Komma vollkommen gleichwertig und wird bei assoziativen Arrays gerne der Übersichtlichkeit halber verwendet, um die Schlüssel-Wert-Paarungen zu verdeutlichen.

Unter UNIX kann auf die Umgebungsvariablen (environment) über das assoziative Array %ENV zugegriffen werden.

Beispiel:

#!/usr/local/bin/perl -w
		

print $ENV{'LOGNAME'}."\n";
print $ENV{'DISPLAY'}."\n";
                  

Variablen

Zu einer "richtigen" Programmiersprache gehören natürlich Variablen, die mit Werten besetzt werden können. Zunächst einmal sollen nur "skalare" Variablen betrachtet werden. Dies sind Zahlen und Zeichenketten (Strings). Im Unterschied zu vielen anderen Sprachen sehen die Variablen für Zahlen und Zeichen in Perl gleich aus: sie beginnen alle mit einem $ gefolgt von einer Kombination aus Buchstaben und Ziffern.

#!/usr/local/bin/perl -w
						  

$ausgabe = "Just another Perl hacker\n";
$i = 123;
$x = 1e-26;


print "$ausgabe\n";
print "$i\n";
print "$x\n";
                  

Just another Perl hacker

123
1e-26
                  

In diesem Beispiel enthält die Variable $ausgabe den Wert Just another Perl hacker\n, die Variable $i den Wert 123 und $x den Wert 1e-26.

Im Unterschied zu den meisten anderen Sprachen müssen Variablen in Perl nicht zu Beginn eines Programms definiert werden. Auch für Zeichenketten muß kein Speicherplatz reserviert werden, ihre Länge ist in Perl nur durch die Größe des Hauptspeichers begrenzt.

Zahlen sind in Perl grundsätzlich Gleitkommazahlen, d.h, es gibt keine Ganzzahlen. Die Genauigkeit entspricht dem Zahlentyp double in C (meist 8 Bytes).

Ob eine Variable als Zahl oder Zeichenkette interpretiert wird, hängt von der Umgebung - dem Kontext - ab, in dem sie auftritt.

#!/usr/local/bin/perl -w
						  

$a = 1;
$b = 4;
$c = $a + $b;
$d = $a . $b;
print "$c\n";
print "$d\n";
                  

5
14
                  

Im obigen Beispiel ist "+" der normale Operator zur Addition zweier Zahlen und "." der Verkettungsoperator, um zwei Strings zu einem zu verbinden.

Lokale Variablen

In einem Unterprogramm kann beliebig auf die (globalen) Variablen des Hauptprogramms zugegriffen werden. Um Variablen lokal zu definieren gibt es die Operatoren local und my. Sie unterscheiden sich in bezug auf Unterprogramme darin, daß Variablen, die in my deklariert werden, nur dort im Unterprogramm definiert sind (genauer: innerhalb des Blockes, in dem sie deklariert werden). Auf "local"-Variablen dagegen kann auch in weiteren Unterprogrammen zugegriffen werden, deren Aufruf innerhalb des Unterprogramms erfolgt, in dem die Variablen deklariert werden.

Beispiel:

#!/usr/local/bin/perl -w
						  

$gl = 1;
$loc = 2;
$my = 3;


print "main: \$gl = $gl   \$loc = $loc   \$my = $my\n";
sub1();
print "main: \$gl = $gl   \$loc = $loc   \$my = $my\n";


sub sub1 {
    local $loc = 7;
    my $my = 8;
	

    print "sub1: \$gl = $gl   \$loc = $loc   \$my = $my\n";
    sub2();
}


sub sub2 {
    print "sub2: \$gl = $gl   \$loc = $loc   \$my = $my\n";
}
                  

main: $gl = 1   $loc = 2   $my = 3
sub1: $gl = 1   $loc = 7   $my = 8
sub2: $gl = 1   $loc = 7   $my = 3
main: $gl = 1   $loc = 2   $my = 3
                  

Wie man sieht, ist $gl überall unverändert verfügbar, während $loc in sub1durch eine neue Variable gleichen Namens ersetzt wird. Deren Wirkung erstreckt sich aber bis in das zweite Unterprogramm. Dagegen ist die Zuweisung $my = 8 nur in sub1 von Bedeutung. An der letzten Ausgabezeile erkennt man, daß die Werte der globalen Variablen von den lokalen Variablen gleichen Namens nicht beeinflusst werden.

Lexikalische Variablen mittels my()

Jede Variable, die "einfach so" (wie diejenigen im Beispiel des vorherigen Abschnittes) verwendet wird, wird in die Symboltabelle des jeweils aktuellen Packages aufgenommen.

Deklariert man dagegen eine Variable mit dem Operator my, so wird die entsprechende Variable in einer anderen Tabelle abgelegt, auf die kein expliziter Zugriff möglich ist.

#!/usr/local/bin/perl

$var_1 = 42;

my $var_2 = "Perl";


foreach $v (keys %::) {      ### Symboltabelle von "main"
   
 if($v =~ /^var/) { print "$v\n" }
}
                    

Hier erscheint in der Programmausgabe nur "$var_1", nicht aber "$var_2".

Neben der Tatsache, daß my-Variablen in einer eigenen Tabelle verwaltet werden, ist von besonderer Bedeutung, daß sie nur einen recht beschränkten Gültigkeitsbereich besitzen. Während nicht besonders deklarierte Variablen (wie $var_1 im obigen Beispiel) im gesamten Package benutzt werden können (und über den voll qualifizierten Namen wie etwa $main::var_1 auch in anderen Packages), so ist eine durch my erzeugte Variable nur in dem aktuellen Block (definiert durch geschweifte Klammern "{...}"), der aktuellen Datei oder innerhalb eine Arguments von eval() zugänglich.

Es kann in einem Package durchaus zwei Variablen gleichen Namens geben: eine in der Symboltabelle und eine, die durch einen Aufruf von my entstanden ist. In einem solchen Falle wird bei einfacher Verwendung des Bezeichners auf die my-Variable zugegriffen.

#!/usr/local/bin/perl -w

$a = "main";

{
    my $a;
    $a = "Block";

   
 print "$a\n";                  ### "Block"
   
 print "$main::a\n";       ### "main"

}
print "$a\n";                 
     ### "main"
                    

Im Block in der Mitte des Programms existiert neben "$a" der Symboltabelle von main (Zugriff über voll qualifizierten Namen "$main::a" möglich) auch eine my-Variable gleichen Namens. Letztere verschwindet aber wieder, sobald der umschließende Block verlassen wird.

Es ist übrigens durchaus möglich, my-Deklarationen zu "schachteln":

#!/usr/local/bin/perl -w


my $a = "main";

{
    my $a;
    $a = "Block";
   
 print "$a\n";   ### "Block"

}
print "$a\n";       
### "main"
                    

Man bezeichnet solche Variablen als lexikalisch, weil deren Gültigkeitsbereich schon alleine durch Untersuchung des Programmcodes feststellbar ist.

Benötigt man in einem Perl-Programm eine lokale Variable, so sollte man im allgemeinen my verwenden. Lediglich in speziellen Situationen ist es angebracht, stattdessen local (siehe nächsten Abschnitt) zu benutzen.

Dynamische Variablen mittels local()

Auch der Operator local schränkt den Gültigkeitsbereich einer Variablen ein. Allerdings unterscheidet sich der Mechanismus grundlegend von dem des Operators my.

Wird eine Variable durch local deklariert, so wird der aktuelle Wert dieser Variablen (sofern vorhanden) gesichert. Anschließend können dieser Variablen neue Werte zugewisen werden. Wird der Block, in dem die local-Deklaration erfolgte, verlassen, so wird der ursprüngliche (gesicherte) Wert wiederhergestellt.

#!/usr/local/bin/perl -w

$a = 123;
print "Main:  $a\n";

{
   
local $a;
   $a = 456;
   print "Block: $a\n";
}

print "Main:  $a\n";
                  

Main:  123
Block: 456
Main:  123
                  

Bei der Deklaration mit local wird keine neue Variable auf irgendeinem Stack erzeugt (wie bei my), sondern es wird nur der Inhalt neu zur Verfügung gestellt. Die entsprechende Variable ist also nach wie vor global zugänglich.

Daß die Variable nach wie vor eine globale Variable ist, erkennt man auch im folgenden Beispiel:

#!/usr/local/bin/perl -w

$x = 'x (main)';
print "Main: \$x = $x\n";

{
    
local $x = 'x (local)';
    print "Block: \$x = $x\n";
    print "Symboltabelle: \$::x = $::x\n";
    unterpr();
}

print "Main: \$x = $x\n";

sub unterpr {
    print "unterpr(): \$x = $x\n";
}
                  

Main: $x = x (main)
Block: $x = x (local)

Symboltabelle: $::x = x (local)
unterpr(): $x = x (local)

Main: $x = x (main)
                  

Sowohl in der (globalen) Symboltabelle als auch in der Subroutine unterpr(), die sich, betrachtet man den Quell-Code des Programms, außerhalb des Blockes mit der local-Deklaration befindet, wird für $x der Wert "x (local)" ausgegeben. Der ursprüngliche Wert wird erst wiederhergestellt, wenn in der Folge des Programmablaufs der Block verlassen wird, in dem die local-Deklaration stattfand.

Da die Gültigkeit von local-Variablen somit durch den Programmablauf bestimmt wird, spricht man auch von Laufzeit- oder dynamischen Variablen.

Unterschiede zwischen my() und local()

Die folgende Tabelle zeigt noch einmal schematisch den Unterschied zwischen my und local. Rot markiert sind diejenigen Werte, die ein " print $v;" an der entsprechenden Stelle im Code ausgeben würde.

  von main my-Variablen local-Stack  
$v = 42; v = 42     Globales $v
{
  local $v = 100;
v = 100   v = 42 Inhalt von $v wird ersetzt
  {
   my $v = 7;
v = 100 v = 7 v = 42 Lexikalische Variable $v
  } v = 100   v = 42 Ende des my-Blocks
} v = 42     Ende des local-Blocks

Auf die Variable in der Symboltabelle kann in diesem Beispiel immer mittels $main::v zugegriffen werden. Existiert zusätzlich eine my-Variable, so bezieht sich $v immer auf diese (nicht auf das globale $v). Ein Zugriff auf den local-Stack ist hingegen nicht möglich.

Eine Situation, in der lokale Variablen nicht mittels my erzeugt werden können, sind die speziellen in Perl vordefinierten Variablen, wie etwa $"(Zeichen, das die Elemente eines Arrays voneinander trennt, wenn es innerhalb von doppelten Anführungszeichen interpoliert wird). Man kann so in einem Programmblock eine Neudefinition einer globalen Variable vornehmen, ohne den ursprünglichen Wert explizit sichern und am Ende wieder zurücksetzen zu müssen.

#!/usr/local/bin/perl -w


$" = ',';
@a = (10,20,30);
print "@a\n";

{
  
local $" = ' - ';
  print "@a\n";
}

print "@a\n";
                  

10,20,30
10 - 20 - 30
10,20,30
                  

 

Spezielle Variablen

In den vorherigen Abschnitten wurden schon einige spezielle Perl-Variablen im Zusammenhang mit der Mustersuche erwähnt; hier eine Übersicht:

  • $& gibt das gefundene Muster zurück
  • $1,$2,$3,... enthält das Muster der 1.,2.,3.,... runden Klammer
  • $+ enthält das Muster der letzten runden Klammer
  • $` enthält die Zeichenkette, die vor dem gefundenen Muster steht
  • $' enthält die Zeichenkette, die hinter dem gefundenen Muster steht

Beispiel:

#!/usr/local/bin/perl -w

$a = "Dies ist ein Test ...";

if($a =~ /is([a-z]) (.*) Test/) {
  print $&."\n";
  print $1."\n";
  print $2."\n";
  print $+."\n";
  print $`."\n";
  print $'."\n";
}
                    
ist ein Test
t
ein
ein
Dies 
 ...
                    

 

reservierte Variablen

Es gibt in Perl einige reservierte Variablen, die Informationen über aktuelle Einstellungen geben und die auch dazu verwendet werden können, einige dieser Einstellungen zu verändern, indem die Variablen entsprechend gesetzt werden.

Anmerkung: Einige der Variablen liefern auf Nicht-UNIX-Betriebssystemen nicht unbedingt sinnvolle Werte (wenn überhaupt), falls die jeweils zugrundeliegende Funktion (z.B. Verwendeung von Benutzer-IDs) nicht zur Verfügung steht.

Die Variable $_

Wenn beispielsweise bei einem Funktionsaufruf der Rückgabewert nicht explizit einer Variablen zugewiesen wird, so wird er oft doch gespeichert, und zwar in der Variablen "$_". Auch können eine Reihe von Funktionen (die eigentlich ein Argument erwarten) ohne Argument aufgerufen werden - es wird dann stillschweigend der Inhalt von $_ übergeben. $_ ist also so etwas wie eine Variable, die temporär Daten aufnimmt, und es daher erlaubt, Funktionsaufrufe miteinander zu verketten, ohne jedes mal explizit Zuweisungen an Variablen vornehmen zu müssen, die sonst nirgendwo im Programm gebraucht werden.

Beispiel:

#!/usr/local/bin/perl -w

$string = 'Hallo';
chop($string);
print $string;
print "\n";

$_ = 'Hallo';
chop($_);
print $_;
print "\n";

$_ = 'Hallo';
chop;
print;
print "\n"; 

                    

Während im ersten Teil eine Variable namens $string verwendet wird, um den Text zu speichern und die anschließenden Funktionsaufrufe durchzuführen, zeigt das zweite Beispiel, daß man als Variable genau sogut $_ verwenden kann. Der dritte Teil demonstriert, wie bei Aufruf der Funktion chop ohne Argument standardmäßig der Inhalt von $_ übergeben wird und das Ergebnis wiederum in $_ landet. Schließlich wird der Inhalt von $_ mit der Funktion print (ebenso ohne Argument) ausgegeben.

Auch wenn im obigen Beispiel $_ wie eine normale Variable verwendet wird, gibt es ein doch ein paar Unterschiede; so ist $_ auch über package -Deklarationen hinweg global, und sie lässt sich auch nicht mit my in einer Subroutine lokalisieren.

Ein weiteres Beispiel:

#!/usr/local/bin/perl -w

@array = ('a', 'b', 'c');

foreach (@array) {
    tr/a-z/A-Z/;
    print;
}    
          
ABC
          

Da hier bei foreach keine Laufvariable angegeben ist, wird $_ angenommen. $_ erhält also nacheinander die Werte "a", "b" und "c". Im Inneren der Schleife wird die Funktion tr auf $_ angewandt (ausführlich sähe dies so aus: $_ =~ tr/a-z/A-Z/;), die hier die Kleinbuchstaben von a bis z durch die entsprechenden Großbuchstaben ersetzt.

Allgemeine Informationen zu Variablen

PID | UID | GID

Fehlermeldungen

Weitere spezielle Variablen

 

Parameter

Die Übergabe von Parametern erfolgt durch das spezielle Array "@_". Somit kann innerhalb des Unterprogramms auf die (im Prinzip beliebig vielen) Parameter über $_[0],$_[1],$_[2],... zugegriffen werden.

Beispiel:

#!/usr/local/bin/perl -w
						
&S(1,2);
&S("aaa","bbb","ccc","ddd");

sub S {
local($i);

for($i = 0;$i < @_;$i++) { print "$_[$i]\n" }
}
						
						

1
2
aaa
bbb
ccc
ddd
                  

Zur Erinnerung: @_ steht im obigen Beispiel im skalaren Kontext und gibt daher die Zahl der Elemente in dem Parameter-Array an.

Rückgabewert

Um einen bestimmten Wert an das aufrufende Hauptprogramm zu liefern, kann die Funktion return() (Klammern optional) verwendet werden. Fehlt eine solche Angabe, so ist der Rückgabewert automatisch das Ergebnis der zuletzt ausgeführten Operation im Unterprogramm.

#!/usr/local/bin/perl -w


$a = &S(7,19);
print $a."\n";
$a = &T;
print $a."\n";

sub S { $_[0] + $_[1] }
sub T { return 100; }
                  

26
100
                  

 

Schleifen und Bedingungen

Bedingte Verzweigung

#!/usr/local/bin/perl -w

for($i = 1;$i <= 5;$i ++) {
  if    ($i < 3)  { print "($i) kleiner als 3\n" }
  elsif ($i == 4) { print "($i) gleich 4\n" }
  elsif ($i > 4)  { print "($i) größer als 4\n" }
  else            { print "($i) keine der anderen Bedingungen erfüllt\n" }
  
  unless($i == 2) { print "[$i] ungleich 2\n" }
}
                  

(1) kleiner als 3
[1] ungleich 2
(2) kleiner als 3
(3) keine der anderen Bedingungen erfuellt
[3] ungleich 2
(4) gleich 4
[4] ungleich 2
(5) groesser als 4
[5] ungleich 2
                  

Das Argument von if ist eine Bedingung, die entweder wahr ("true") oder falsch ("false") ist. Im Falle von "wahr" wird der Block nach if ausgeführt. Ist die if-Bedingung falsch, so wird (falls vorhanden) das Argument des ersten elsif ausgewertet. Liefert auch dieses nicht den Wert true, kommt das nächste elsif an die Reihe; so lange bis entweder eine Bedingung wahr ist, keine Bedingungen mehr vorhanden sind oder ein abschließendes else erreicht wird, dessen Block ausgeführt wird, falls kein anderer Block infrage kommt.

Im Gegensatz zu anderen Programmiersprachen wie z.B. C muß der Block nach einem if, elsif oder else immer in geschweiften Klammern stehen; dadurch werden eventuelle Mehrdeutigkeiten vermieden.

Das Gegenstück von if ist unless, dessen Block nur ausgeführt wird, wenn die Bedingung im Argument den Wert false liefert.

Eine Alternative zu einer if- else-Konstruktion ist die Verwendung des Operators "?:":

$a == 1 ? print "a gleich 1" : print "a ungleich 1";
                  

while und until

 

#!/usr/local/bin/perl -w

$i = 0;
while($i < 10) {
  print "$i\n";
  $i += 2;
}
until($i == 5) {
  print "$i\n";
  $i --;
}
                  

Bei der while-Schleife wird zuerst das Argument überprüft. Falls dies true liefert, wird der Schleifenblock ausgeführt. Dies wiederholt sich so lange, bis das while-Argument false ist.

Die Negation der while-Schleife ist die Konstruktion mit Hilfe von until. Hier wird der Schleifenkörper so lange wiederholt bis das Argument von until den Wert true liefert. Obiges Programm liefert demzufolge die Ausgabe

0
2
4
6
8
10
9
8
7
6
                  

for und foreach

Folgendes Programm schreibt die Zahlen von 1 bis 10 auf den Bildschirm:

#!/usr/local/bin/perl -w

for($i = 1;$i <= 10;$i++) { print "$i\n"; }
                  

Zu allererst wird die Anweisung im 1.Argument von for ausgeführt. Anschließend wird das 2.Argument überprüft. Liefert diese Abfrage eine wahre Aussage (true), so wird der Schleifenblock ausgeführt. Nach dem Block wird das 3.Argument von for ausgewertet und dann wieder das Argument Nummer 2 überprüft. Dies wiederholt sich so lange, bis die Bedingung (Argument 2) nicht mehr erfüllt ist (Wert false). Dann fährt das Programm in der Zeile nach dem Schleifenblock fort.

Die for-Schleife ist eigentlich nur eine vereinfachte Schreibweise; obiges Beispielprogramm läßt sich auch wie folgt schreiben:

#!/usr/local/bin/perl -w

$i = 1;
while($i <= 10) {
  print "$i\n";
  $i++;
}
                  

Anstatt der drei durch Semikolons getrennten Argumente, kann for auch eine Liste übergeben werden, die dann sukzessive abgearbeitet wird. Aus Gründen der Übersichtlichkeit sollte in so einem Falle aber an Stelle von for das äquivalente foreach stehen. Die einzelnen Zeilen des folgenden Skripts leisten alle das gleiche: Sie geben die Zahlen von 1 bis 10 aus.

#!/usr/local/bin/perl -w

for((1,2,3,4,5,6,7,8,9,10)) { print $_."\n" }
foreach((1,2,3,4,5,6,7,8,9,10)) { print $_."\n" }
foreach(1..10) { print $_."\n" }
foreach $nr (1..10) { print $nr."\n" }
                  

In der letzten Zeilen sieht man, wie das gerade von foreach bearbeitete Listenelement einer Variablen zugewiesen werden kann. Wird keine solche Variable angegeben, so steht der aktuelle Listenwert in der speziellen Variablen $_.

Dateifunktionen

Globbing

In einer UNIX-Shell gibt es die Möglichkeit, eine Liste von Files zu erhalten, indem man ein Muster vorgibt, das Platzhalter wie * oder ? enthält. So liefert

ls -1 *.html

                  

eine einspaltige Liste aller Files, die auf .html enden.

Einen analogen Mechanismus gibt es in Perl durch die Funktion glob() sowie den sog. Rhombus-Operator <>. Obiges Shell-Beispiel lässt sich dann wie folgt implementieren:

Oder auch:

#!/usr/local/bin/perl -w


foreach $filename (<*.html>) {
  print $filename."\n"
}
                  

Man kann auch die Fileliste direkt an ein Array übergeben:

#!/usr/local/bin/perl -w


$pfad = 'perl';
@fileliste = <$pfad/*.html>;
foreach $filename (@fileliste) { print $filename."\n" }

$muster = '*.html';
@fileliste = <${muster}>;          # Spezialfall ...
foreach $filename (@fileliste) { print $filename."\n" }
                  

Im obigen Beispiel muss im zweiten Teil <${muster}> anstelle von <$muster> stehen, da hier eine Variable alleine im Rhombus-Operator steht.

Wer es etwas genauer wissen will: in einem Ausdruck wie <$muster> wird $muster als "indirektes Filehandle" betrachtet. Damit kann man beispielsweise Filehandles als Parameter an Unterprogramme übergeben.

Beispiel:

#!/usr/local/bin/perl -w


open(FILE,'test.dat');
print_file(\*FILE);
close(FILE);


sub print_file {
    my $handle = $_[0];
    while(<$handle>) { print }
}
                  

Verzeichnisse

Ähnlich wie man Dateien zum Lesen öffnen kann, lassen sich auch Verzeichnisse behandeln, um auf die Dateinamen des Ordnerinhalts zugreifen zu können.

Beispiel:

#!/usr/local/bin/perl -w

opendir(DIR,"perl");
while($datei = readdir(DIR)) { print $datei."\n" }
closedir(DIR);
                  

Mit opendir() wird dabei das Verzeichnis geöffnet. Das erste Argument ist hierbei das sog. "Directoryhandle", dessen Name (aus Gründen der Konvention) aus Großbuchstaben bestehen sollte. Die Funktion readdir() liefert dann die einzelnen Einträge des Ordners. closedir() schließlich beendet den Zugriff auf das Verzeichnis.

Das aktuelle Verzeichnis kann durch `pwd` bestimmt werden. Zu beachten sind hier die sog. backquotes (``) ! Sie bewirken, daß die eingeschlossene Zeichenkette als Kommando an das Betriebssytem weitergegeben wird. Das Ergebnis des Kommandos wird dann zurückgeliefert.

Beispiel:

#!/usr/local/bin/perl -w

$akt_verz = `pwd`;
print "aktuelles Verzeichnis : $akt_verz\n";
                  

Ein Verzeichniswechsel ist durch die Funktion chdir() möglich. Dies ist allerdings abhängig vom Betriebssystem, unter dem Perl gerade läuft, wobei insbesondere auf das Zeichen zu achten ist, das Datei-/Verzeichnisnamen im Pfad voneinander trennt.

Als Beispiel seien hier UNIX und MacOS gegenübergestellt:

                       | UNIX              | MacOS
 ----------------------+-------------------+---------------------
  Pfad-Trennzeichen    | /                 | : 
                       |                   |
  Wechseln in höheres  | chdir('..');      | chdir('::');   
  Verzeichnis          |                   |
                       |                   |
  Öffnen des aktuellen | opendir(ABC,'.'); | opendir(ABC,':');
  Verzeichnisses       |                   |
                  

Dateifunktionen

Zum Arbeiten mit Dateien gibt es folgende Funktionen; abhängig vom Betriebssystem stehen nicht immer alle zur Verfügung (z.B. gibt es keine Hard Links auf der Macintosh-Plattform):

  • Änderung des Namens: rename()
    #!/usr/local/bin/perl -w
    
          rename("alter_name","neuer_name");
                        
  • Löschen einer Datei: unlink()
    #!/usr/local/bin/perl -w
    
    
          unlink("dateiname");
                        
  • Erzeugen eines Verzeichnisses: mkdir()
    #!/usr/local/bin/perl -w
    
    
          $permissions = 0777;
          mkdir("dirname",$permissions);
                        
  • Löschen eines (leeren) Verzeichnisses: rmdir()
    #!/usr/local/bin/perl -w
    
    
          rmdir("dirname");
                        
  • Hard Link erzeugen: link()
    #!/usr/local/bin/perl -w
    
    
          link("filename","linkname");
                        
  • Soft Link erzeugen: symlink()
    #!/usr/local/bin/perl -w
    
    
          symlink("filename","linkname");
                        
  • Ändern der Zugriffsrechte: chmod()
    #!/usr/local/bin/perl -w
    
    
          $permissions = 0755;
          chmod($permissions,"prog_1","prog_2","prog_3");
                        
  • Ändern des Besitzers: chown()
    #!/usr/local/bin/perl -w
    
    
          $uid = 4987;                      # Benutzer-ID
          $gid = 33;                        # Gruppen-ID
          chown($uid,$gid,"datei");
                        
  • Ändern der Zeitdaten: utime()
    #!/usr/local/bin/perl -w
    
    
          $access = 812_000_000;           # letzter Zugriff
          $modif =  822_000_000;            # letzte Aenderung
          utime($access,$modif,"datei");
                        

    Die Zeiten sind hierbei in Sekunden seit dem 1.1.1970 anzugeben. Die aktuelle Systemzeit kann über den Operator time abgefragt werden:

    #!/usr/local/bin/perl -w
    
    
          print "Seit dem 1.1.1970 sind ";
          print time;
          print " Sekunden vergangen.\n";
                        

Formate

Eine einfache Möglichkeit, Protokolle oder Tabellen übersichtlich auszugeben, bieten sogenannte Formate. Dort können beispielsweise Spalten einer Tabelle definiert werden; jeweils mit Breite und Positionierung des Eintrags (rechts-, linksbündig oder zentriert). Außerdem kann ein Seitenkopf definiert werden, der bei Ausgaben, die sich über mehrere Seiten erstrecken, auf jeder einzelnen Seite vor den eigentlichen Daten ausgedruckt wird.

Um Daten formatiert auszugeben, muss der Befehl write (optional mit einem Filehandle) benutzt werden. Es können für jedes Filehandle unabhängig voneinander Formate definiert werden.

Definition eines Formats

Das Schema einer Formatdefinition sieht wie folgt aus:

format <Name> =
<Musterzeile>
<Variablenzeile>
.

Im einfachsten Falle ist der Name eines Formats gleich dem Namen des Filehandles, für das das Format verwendet werden soll (Standardwert: STDOUT). Will man einer Formatdefinition einen anderen Namen geben, so kann die entsprechende Zuordnung von Formatname und aktuellem Filehandle durch Setzen der Variablen $~ geschehen.

Um bei mehrseitigen Dokumenten jeweils automatisch einen Seitenkopf ausgeben zu lassen, kann ein spezielles Format hierfür definiert werden. Der Name wird gebildet durch das Anhängen von "_TOP" an das Filehandle (Standardwert: STDOUT_TOP). Alternativ dazu kann eine beliebiger Name durch Setzen von $^ verwendet werden. Ansonsten erfolgt die Definition vollkommen analog zu der eines normalen Formats.

Die Musterzeile enthält die Definitionen der einzelnen Felder, in die dann später die Werte der Variablen der darauffolgenden Zeile eingetragen werden. Es dürfen mehrere Muster- und Variablenzeilen angegeben werden; allerdings ist darauf zu achten, dass sie immer paarweise auftreten (jede Variablenliste "füllt" die darbüberstehende Musterzeile).

Außerdem können noch überall Kommentarzeilen eingefügt werden, die mit einem '#' beginnen.

Die Definitionen von Formaten dürfen an beliebiger Stelle im Programmcode stehen (wie Unterprogramme).

Musterzeile

Jede dieser Zeilen bestimmt Felder in der Ausgabe, in die dann Variablenwerte (festgelegt in der jeweils darauffolgenden Zeile) eingesetzt werden sollen.

Ein normales Feld besteht aus einem '@' gefolgt von null oder mehr Positionierungszeichen eines Typs:

'<' (linksbündig)

'|' (zentriert)

'>' (rechtsbündig)

Beispiel:

#!/usr/local/bin/perl -w


$a = 12;

write;

format STDOUT =
#    eine Spalte, vierstellig, zentriert
@|||
$a
.
                    

 12
                  

Eine mehrzeilige Ausgabe von Zeichenketten wird durch Felder bewerkstelligt, die mit einem '^' beginnen. Dabei wird dann dort, wo das Feld in der Formatdefinition zum ersten Mal erscheint, ein möglichst großer Teil des Ausgabestrings dargestellt. Beim zweiten Auftreten wird ggf. dann ein Teil des Restes dargestellt, usw. (Achtung: in der Zeichenkette wird dabei sukzessive der jeweils dargestellte Teil entfernt, d.h., der Wert der Stringvariablen ändert sich u.U. bei jedem write).

Beispiel:

#!/usr/local/bin/perl -w


$text = "Dies ist ein Beispiel dafuer, wie einem Format mehrzeilige ";
$text .= "Texteintraege dargestellt werden koennen.";

write;

format STDOUT =
#    bis zu drei Zeilen Text
                  

Dies ist ein Beispiel dafuer,
wie einem Format mehrzeilige
Texteintraege dargestellt ...
                  

Oft weiß man vorher nicht, wie lang der Text wird. Um unnötige Leerzeilen zu vermeiden, setzt man einfach in die entsprechende Musterzeile eine Tilde ('~'). Will man einen längeren Text auf jeden Fall komplett ausgeben, so kann man dies durch zwei aufeinanderfolgende Tilden ('~~') in einer Musterzeile erreichen. In diesem Falle wird die Ausgabe dieser Zeile so oft wiederholt bis die Zeichenkette in der dazugehörenden Stringvariable vollständig dargestellt ist. Schließlich kann ein Text in seiner natürlichen Zeilenaufteilung in ganzer Länge ausgegeben werden, indem der Stringvariablen in der Musterzeile das Feld '@*' zugeordnet wird.

Eine besondere Art der Positionierung bietet das '#'. Nach einem '@' bewirkt es eine rechtsbündige Darstellung, wobei bei der Ausgabe einer Zahl ein optionaler Dezimalpunkt berücksichtigt wird. Nach einem '^' wird ein so markiertes Feld nur dann dargestellt, wenn die dazugehörende Variable definiert ist.

Beispiel:

#!/usr/local/bin/perl -w

$a = 117.127;
write;

format STDOUT =
Betrag: @###.## € (^###)
$a, $b
.
                    

Betrag:  117.13 € (    )
                  

Variablenzeile

Eine Zeile dieser Art legt fest, welche Variablenwerte in die jeweils vorangegangene Musterzeile eingetragen werden sollen.

Dies kann einfach durch eine durch Kommata getrennte Liste sein; aber es ist auch möglich, Arrays (die mehrere Felder der Musterzeile abdecken) oder gar ganze Ausdrücke