| perlintro Dokumentation | Download als POD | Wie kann ich hier etwas ändern? |
perldoc -Kommando lesen oder mit der Methode, welcher auch immer, mit der gerade dieses Dokument gelesen wird.
perl program.pl
Alternativ kann man auch folgende Zeile:
#!/usr/bin/env perl
an den Anfang des Skriptes packen und das skript mit /path/to/script.pl aufrufen. Dafür muss es natürlich ausführbar sein, also chmod 755 script.pl (unter Unix).
Für mehr Informationen, z.B. Instruktionen für andere Betriebssysteme wie Windows und Mac OS, siehe perlrun.
main() o.ä. zu haben.
Perl Statements enden mit einem Semikolon:
print "Hello, world";
Kommentare beginnen mit dem Gatter- ("#") Zeichen und gehen bis zum Ende der Zeile:
# This is a comment
Nichtdruckbare Zeichen ("whitespaces") spielen keine Rolle:
print
"Hello, world"
;
ausser in gequoteten Strings:
# das würde einen Zeilenumbruch in der Mitte drucken
print "Hello
world";
Double- oder Singlequotes können beide für wortgetreue Strings benutzt werden:
print "Hello, world";
print 'Hello, world';
Allerdings werden Variablen und spezielle Zeichen nur in doppelten Anführungszeichen ("double quotes") interpoliert, z.B. der Zeilenumbruch ( \n ):
print "Hello, $name\n"; # klappt prima
print 'Hello, $name\n'; # liefert $name\n wortgetreu
Zahlen brauchen keine Quotes:
print 42;
Man kann Klammern für Funktionenargumente benutzen oder auch weglassen, je nach Geschmack. Man braucht sie nur, um die Reihenfolge festzulegen.
print("Hello, world\n");
print "Hello, world\n";
Genauere Informationen über Perlsyntax kann man in perlsyn finden.
Ein Skalar repräsentiert einen einzigen Wert:
my $animal = "camel";
my $answer = 42;
Skalare Werte können Strings, Integer oder Floatingpoint-Zahlen sein, und Perl konvertiert sie je nach Bedarf um. Man braucht Variablen also nicht vorzudeklarieren.
Skalare können auf verschiedene Arten genutzt werden:
print $animal;
print "The animal is $animal\n";
print "The square of $answer is ", $answer * $answer, "\n";
Es gibt eine Reihe "magischer" Skalare mit Namen, die wie Interpunktion oder das Rauschen auf einer gestörten Leitung ("line noise") aussehen. Diese speziellen Variablen werden für alle möglichen Zwecke benutzt und sind in perlvar dokumentiert. Die einzige, die man für den Anfang braucht, ist $_ , auch Standardvariable ("default variable") genannt. Sie wird als Standardargument für einige Funktionen in Perl benutzt, und implizit durch einige Schleifenkonstrukte gesetzt.
print; # druckt den Inhalt von $_
Ein Array repräsentiert eine Liste von Werten:
my @animals = ("camel", "llama", "owl");
my @numbers = (23, 42, 69);
my @mixed = ("camel", 42, 1.23);
Arrays beginnen mit dem Index 0. So kommt man an die Elemente:
print $animals[0]; # druckt "camel"
print $animals[1]; # druckt "llama"
Die spezielle Variable $#array gibt den letzten Index des Arrays an:
print $mixed[$#mixed]; # letztes Element, liefert 1.23
Jetzt könnte man versucht sein, $#array + 1 für die Anzahl der Elemente zu benutzen, aber diese Mühe braucht man sich nicht zu machen, denn netterweise liefert Perl, wenn man @array in einem skalaren Kontext verwendet, (also dort, wo Perl eigentlich eine Zahl erwarten würde), die Anzahl der Elemente:
if (@animals < 5) { ... }
Die Elemente, die wir aus dem Array lesen, fangen mit "$" an, da es einzelne Werte sind -- frag nach einem Skalar, und du kriegst einen Skalar.
Um mehrere Werte aus einem Array zu bekommen, tut man dies:
@animals[0,1]; # liefert ("camel", "llama");
@animals[0..2]; # liefert ("camel", "llama", "owl");
@animals[1..$#animals]; # liefert alles ausser dem ersten Element
Man kann verschiedene nützliche Sachen mit Arrays machen:
my @sorted = sort @animals;
my @backwards = reverse @numbers;
Es gibt auch ein paar spezielle Arrays, wie z.B. @ARGV (die Argumente der Kommandozeile) und @_ (die Argumente, die der aktuellen Subroutine übergeben wurden). Diese sind in perlvar dokumentiert.
Ein Hash repräsentiert einen Satz von Schlüssel/Werte-Paaren:
my %fruit_color = ("apple", "red", "banana", "yellow");
Man kann Whitespaces und den "=>" Operator verwenden, um die Beziehung etwas lesbarer zu gestalten:
my %fruit_color = (
apple => "red",
banana => "yellow",
);
Um an Hash-Elemente zu kommen, verwendet man:
$fruit_color{"apple"}; # liefert "red"
Mit keys() und values() kommt man eine Liste der Schlüssel bzw. Werte des Hashs:
my @fruits = keys %fruit_color;
my @colors = values %fruit_color;
Hashes haben keine bestimmte Reihenfolge, aber man kann die Werte sortieren und eine Schleife darüberlaufen lassen.
Genau wie spezielle Skalare und Arrays gibt es auch spezielle Hashes. Der bekannteste ist wohl %ENV , welcher Umgebungsvariablen beinhaltet. Alles darüber (und andere spezielle Variablen) erfährt man in perlvar.
my $variables = {
scalar => {
description => "single item",
sigil => '$',
},
array => {
description => "ordered list of items",
sigil => '@',
},
hash => {
description => "key/value pairs",
sigil => '%',
},
};
print "Scalars begin with a $variables->{'scalar'}->{'sigil'}\n";
Vollständige Informationen bezüglich Referenzen finden sich in perlreftut , perllol , perlref und perldsc .
my $var = "value";
Das my ist eigentlich gar nicht notwendig; man könnte einfach sagen:
$var = "value";
Jedoch würde diese Syntax globale Variablen im ganzen Programm kreieren, was eine schlechte Programmierpraxis ist. "my" kreiert stattdessen lexikalisch begrenzte Variablen. Die Variablen sind begrenzt auf den Block (also in etwa eine Befehlsfolge umgeben von geschweiften Klammern), in dem sie definiert sind.
my $a = "foo";
if ($some_condition) {
my $b = "bar";
print $a; # liefert "foo"
print $b; # liefert "bar"
}
print $a; # liefert "foo"
print $b; # liefert nichts; $b ist aus seinem Bereich heraus
Die Benutzung von my in Kombination mit use strict; am Anfang des Skripts bedeutet, dass der Interpreter übliche Programmierfehler findet. Etwa im Beispiel oben würde das letzte print $b einen Kompilerfehler erzeugen und das Programm erst gar nicht starten. Die Benutzung von strict ist dringend zu empfehlen.
if ( condition ) {
...
} elsif ( other condition ) {
...
} else {
...
}
Es gibt auch die negierte Version von if:
unless ( condition ) {
...
}
Das ist die lesbarere Variante von if (condition) .
Man merke sich, dass die Klammern benötigt werden, auch wenn man bloss eine Zeile in dem folgenden Block hat. Es gibt allerdings einen cleveren Weg, um solche bedingten Ausdrücke etwas "englischer" aussehen zu lassen:
# traditionell
if ($zippy) {
print "Yow!";
}
# der perlische Weg mit nachgestellter Bedingung
# ("post-conditioning", sogenannte "Bedingte Ausdrücke")
print "Yow!" if $zippy;
print "We have no bananas" unless $bananas;
while ( condition ) {
...
}
Dafür gibt es auch eine negierte Version, aus demselben Grund, aus dem wir unless haben:
until ( condition ) {
...
}
Man kann auch while in einem bedingten Ausdruck verwenden:
print "LA LA LA\n" while 1; # Endlos-Schleife
Genau wie in C:
for ($i=0; $i <= $max; $i++) {
...
}
Die C-Style-for-Schleife wird in Perl kaum gebraucht, da Perl die benutzerfreundlichere List-Scanning foreach - Schleife zur Verfügung stellt.
foreach (@array) {
print "This element is $_\n";
}
# man muss nicht den Standard $_ benutzen
foreach my $key (keys %hash) {
print "The value of $key is $hash{$key}\n";
}
perlsyn . (Anm. der Übersetzerin: "for" ist nur ein Alias für "foreach" und austauschbar, funktioniert also genauso und ist Geschmackssache)
print , sort und reverse . Eine Liste gibt es am Anfang von perlfunc, und Informationen zu einer bestimmten Funktion bekommt man recht einfach mit perldoc -f funktionsname .
Perl-Operatoren sind vollständig dokumentiert in perlop. aber hier sind ein paar der üblichen:
+ Addition
- Subtraktion
* Multiplikation
/ Division
== Gleichheit
!= Ungleichheit
< kleiner als
> grösser als
<= kleiner als oder gleich
>= grösser als oder gleich
eq Gleichheit
ne Ungleichheit
lt kleiner als
gt grösser als
le kleiner als oder gleich
ge grösser als oder gleich
(Warum gibt es separate numerische und Zeichenketten-Vergleiche? Weil es keine speziellen Variablentypen gibt, und Perl muss wissen, ob es numerisch sortieren soll (wo 99 kleiner als 100 ist) oder alphabetisch (wo 100 vor 99 kommt).)
&& and
|| or
! not
( and , or und not sind nicht nur die Beschreibungen der Operatoren -- sie sind selbst Operatoren. Sie sind lesbarer als C-Style-Operatoren, aber haben andere Prioritäten als && und Co. Siehe perlop für Details.)
= Zuweisung
. Zeichenketten-Verkettung
x Zeichenketten-Multiplikation
.. Bereichs-Operator (kreiert eine Liste von Zahlen)
= kombiniert werden:
$a += 1; # $a = $a + 1
$a -= 1; # $a = $a - 1
$a .= "\n"; # $a = $a . "\n";
open -Funktion öffnen. Es ist wirklich detailreich in perlfunc und perlopentut dokumentiert, aber hier ist das wichtigste:
open(INFILE, "input.txt") or die "Kann input.txt nicht öffnen: $!"; open(OUTFILE, ">output.txt") or die "Kann output.txt nicht öffnen: $!"; open(LOGFILE, ">>my.log") or die "Kann logfile nicht öffnen: $!";Man kann aus einem geöffneten Filehandle mittels des
<> Oprators lesen. In skalarem Kontext wird eine Zeile aus dem Filehandle eingelesen, und in List-Kontext wird die ganze Datei eingelesen und jede Zeile einem Element der Liste zugewiesen:
my $line = <INFILE>; my @lines = <INFILE>;Die ganze Datei auf einmal einzulesen wird auch "slurping" genannt. Es kann sehr nützlich sein, aber auch speicherverschwendend. Meistens kann man, wenn man Text-Dateien einliest, die Datei zeilenweise verarbeiten, indem man Schleifen verwendet. Den
<> Operator sieht man meistens in while -Schleifen:
while (<INFILE>) { # weist jede zeile der Variable $_ zu
print "Just read in this line: $_";
}
Wir haben schon gesehen, wie man mittels print auf den standard output schreibt. print kann man aber auch noch ein optionales erstes Argument übergeben, und zwar den Filehandle, in den geschrieben werden soll:
print STDERR "This is your final warning.\n"; print OUTFILE $record; print LOGFILE $logmessage;Wenn man mit einem Filehandle fertig ist, sollte man es mittels
close schliessen (um ehrlich zu sein, erledigt das Perl auch am Ende, falls man es vergisst):
close INFILE;
if (/foo/) { ... } # wahr, falls $_ "foo" enthält
if ($a =~ /foo/) { ... } # wahr, falls $a "foo" enthält
Der // matching Operator ist in perlop dokumentiert. Er arbeitet standardmäßig auf $_ , oder kann mit dem binding-Operator =~ (auch in perlop) an eine Variable gebunden werden.
s/foo/bar/; # ersetzt foo mit bar in $_ $a =~ s/foo/bar/; # ersetzt foo mit bar in $a $a =~ s/foo/bar/g; # ersetzt ALLE VORKOMMEN von foo mit bar in $a
Der s/// Substitutions-Operator ist in perlop dokumentiert.
Man muss nicht nur auf feste Zeichenketten matchen. Tatsächlich kann man auf so ziemlich alles matchen, was man sich vorstellen kann, wenn man komplexere reguläre Ausdrücke verwendet. Eine ausführliche Dokumentation findet man in perlre, aber hier ist schonmal eine Tabelle zum Nachschauen:
. Ein einzelnes Zeichen \s whitespace-Zeichen (Leerzeichen, Tab, Zeilenumbruch) \S kein whitespace \d Ziffer (0-9) \D keine Ziffer \w Wort-Zeichen (a-z, A-Z, 0-9, _) \W kein Wort-Zeichen [aeiou] matcht ein Zeichen der gegebenen Menge [^aeiou] matcht ein Zeichen nicht in der gegebenen Menge (foo|bar|baz) matcht eine der 3 Alternativen ^ Anfang der Zeichenkette $ Ende der Zeichenkette
Quantifikatoren können benutzt werden, um festzulegen, wieviele der vorangegangenen Dinge man matchen möchte, wobei "Ding" entweder ein einzelnes Zeichen, einer der Meta-Zeichen von oben, oder eine Gruppe von Zeichen oder Meta-Zeichen in Klammern meint.
* 0 oder mehr des vorherigen Dings
+ 1 oder mehr des vorherigen Dings
? 0 oder 1 des vorherigen Dings
{3} genau 3 des vorherigen Dings
{3,6} zwishen 3 and 6 des vorherigen Dings
{3,} 3 oder mehr des vorherigen Dings
Ein paar kurze Beispiele:
/^\d+/ String beginnt mit einem oder mehreren Ziffen
/^$/ leerer string (Anfang und Ende folgen aufeinander)
/(\d\s){3}/ drei Ziffern, jede gefolgt von einem whitespace
(z.B. "3 4 5 ")
/(a.)+/ matcht einen String, in dem jedes zweite (ungerade)
Zeichen ein "a" ist (z.B. "abacadaf")
# Diese Schleife liest aus STDIN und druckt nur nicht-leere Zeilen
while (<>) {
next if /^$/;
print;
}
Außer zum Gruppieren haben Klammern noch eine weitere Funktion. Sie können benutzt werden, um Ergebnisse eines Teils der Regex (regulärer Ausdruck) zu speichern. Die Ergebnisse finden sich in $1, $2, und so weiter.
# ein billiger und übler Weg, eine email-Adresse in Teile zu splitten
if ($email =~ /([^@])+@(.+)/) {
print "Username is $1\n";
print "Hostname is $2\n";
}
Perl regexps unterstützden ausserdem "back"-referenzen, lookaheads und jede art von anderen komplexen Details. Um alles darüber zu erfahren, lese man perlrequick, perlretut und perlre.
sub log {
my $logmessage = shift;
print LOGFILE $logmessage;
}
Was ist das shift dort? Nun ja, die Argumente einer Subroutine finden sich in einem speziellen Array @_ (siehe perlvar für Details). Das Standardargument für die shift -Funktion ist zufälligerweise @_ . Also macht my $logmessage = shift; nichts anderes als das erste Element der Argumenten-Liste zu shiften und $logmessage zuzuweisen.
Man kann auf @_ noch auf andere Arten zugreifen:
my ($logmessage, $priority) = @_; # üblich my $logmessage = $_[0]; # unüblich, und häßlichSubroutinen können auch Werte zurückgeben:
sub square {
my $num = shift;
my $result = $num * $num;
return $result;
}
Für Details über Subroutinen siehe perlsub.
perldoc _Module::Name _ . Üblicherweise benutzt man use Module::Name , was einem die Benutzung der exportierten Funktionen oder der OO-Schnittstelle des Moduls erlaubt.
perlfaq enthält Fragen und Antworten zu vielen üblichen Problemen und Aufgaben, und hat oft Vorschläge, welche guten CPAN-Module man benutzen könnte.
perlmod beschreibt Perl-Module allgemein. perlmodlib listet die Module auf, die in der Distribution enthalten sind.
Wer den Drang verspürt, Perl-Module zu schreiben, kann sich guten Rat bei perlnewmod holen.
| I | Attachment | Action | Size | Date | Who | Comment |
|---|---|---|---|---|---|---|
| |
perlintro.pod | manage | 21.5 K | 2005-04-27 - 00:00 | HaraldBongartz | kleine Änderungen |