Perl Mongers :: deutschsprachig - German.pm

A wiki for German-speaking Perl programming language user groups.

Änderungen, Hilfe

Treffen, Veranstaltungen

Leute, Gruppen, Ziele

PerlLernen

Best of Perl Books
Die Besten Bücher

ErfolgsStories

Links, FAQ, Forum

Mailing List

Impressum


Liebe(r) Perl Monger(in),

diese Site ist bereits seit langem ein Ziel von Spamrobotern. Neu ist, dass ich das Aufräumen leid bin. Darum schreibe mir eine Mail mit Deinem Usernamen und einem Crypt Passwort, damit Du einen passwortgeschtzten Zugang zu dieser Site von mir erhältst. Eines baldigen Tages wirst Du den brauchen, um hier weiterhin Seiten verändern zu können.

Vielen Dank, Sören


Amazon-Angebote... (Einkauf über diesen Link sponsort den Unterhalt von perlmongers.de)
  1. NAME
  2. BESCHREIBUNG
    1. Was ist Perl
    2. Perlprogramme starten
    3. Grundlegender Syntaxüberblick
    4. Perls Variablen-Typen
    5. Variablen-Begrenzung
    6. Bedingungen und Schleifenkonstrukte
    7. Builtin-Operatoren und Funktionen
    8. Dateien und I/O
    9. Reguläre Ausdrücke
    10. Subroutinen schreiben
    11. OO Perl
    12. Perl-Module benutzen
  3. AUTOR
  4. ÜbersetzerInnen, Credits
  5. Hinweise

NAME

perlintro -- Eine kurze Einführung in Perl

BESCHREIBUNG

Dieses Dokument soll einen schnellen Überblick der Programmiersprache Perl geben, zusammen mit Verweisen auf weitere Dokumentation. Es soll als schrittweises Handbuch für Neulinge dienen, und bietet gerade genug Informationen, mit denen man anderer Leute Perlcode lesen kann und grob verstehen kann, was er tut, oder um eigene kleine Skripte zu schreiben.

Diese Einführung zielt nicht darauf ab, komplett zu sein, und noch nicht einmal darauf, gänzlich korrekt zu sein. In manchen Fällen musste die Perfektion geopfert werden mit dem Ziel, die Idee an sich rüberzubringen. Es ist dringend zu empfehlen, diese Einführung begleitend mit dem Rest der Dokumentation, zu finden in perltoc, zu lesen.

Verstreut in diesem Dokument finden sich Verweise zu anderen Teilen der Perl-Dokumentation. Diese kann man mit dem perldoc-Kommando lesen oder mit der Methode, welcher auch immer, mit der gerade dieses Dokument gelesen wird.

Was ist Perl?

Perl ist eine Mehrzweck-Programmiersprache, die ursprünglich zur Textmanipulation entwickelt wurde und mittlerweile für einen grossen Bereich von Aufgaben verwendet wird, u.a. Systemadministration, Web Development, Netzwerkprogrammierung, GUI Entwicklung, und mehr.

Die Sprache ist dazu gedacht, eher praktisch zu sein (leicht zu benutzen, effizient, komplett) als schön (winzig, elegant, minimal). Ihre beste Eigenschaft ist, dass sie einfach zu benutzen ist, sowohl prozedurale als auch Objekt-Orientierte (OO) Programmierung unterstützt, mächtige built-in-Werkzeuge für Textverarbeitung hat und eine der beeindruckendsten Sammlungen von Modulen Dritter.

Verschiedene Definitionen von Perl gibt es in perl, perlfaq1 und mit Sicherheit an noch anderen Stellen. Daher können wir annehmen, dass Perl verschiedenen Personen verschiedenes bedeutet, aber das viele Leute denken, dass es sich zumindest lohnt, darüber zu schreiben.

Perlprogramme starten

Um ein Perlprogramm von der Unix-Kommandozeile zu starten:

perl program.pl

Alternativ kann man auch folgende Zeile:

#!/usr/bin/env perl

an den Anfang des Skriptes packen und das skript mit /path 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.

Grundlegender Syntaxüberblick

Ein Perlskript besteht aus einem oder mehreren Statements. Diese Statements werden in einfacher Weise ins Skript geschrieben. Es ist nicht nötig, beispielsweise eine Funktion 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.

Perls Variablen-Typen

Perl hat drei wichtige Variablentypen: Skalare, Arrays und Hashes.

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.

Skalare, Arrays und Hashes werden ausführlich in perldata behandelt.

Komplexere Datentypen können mit Referenzen erstellt werden, die es erlauben, Listen und Hashes innerhalb von Listen und Hashes zu bilden.

Eine Referenz ist ein Skalarer Wert und kann zu jedem anderen Perldatentyp referenzieren. So kann man durch Speichern einer Referenz in einem Array/Hash-Element recht einfach Listen und Hashes innerhalb von Listen und Hashes kreieren. Das folgende Beispiel zeigt einen Hash mit zwei Ebenen, indem anonyme Hashreferenzen benutzt werden.

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.

Variablen-Begrenzung

In den vorhergehenden Abschnitten haben die Beispiele alle folgende Syntax verwendet:

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.

Bedingungen und Schleifenkonstrukte

Perl hat die meisten üblichen Bedingungen und Schleifenkonstrukte ausser case/switch (aber wer's wirklich möchte, kann das Switch- Modul ab Perl 5.8 benutzen; erhältlich bei CPAN. Siehe den Abschnitt über Module weiter unten für Informationen über Module und CPAN).

Die Bedingungen können aus jedem beliebigen Perl-Ausdruck bestehen. Siehe die Liste der Operatoren im nächsten Abschnitt für Informationen über Vergleichs- und boolesche logische Operatoren, die üblicherweise in Bedingungen verwendet werden.

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";
}

Für mehr Details bezüglich Schleifen (und andere Konstrukte, die hier nicht erwähnt wurden), siehe perlsyn. (Anm. der Übersetzerin: "for" ist nur ein Alias für "foreach" und austauschbar, funktioniert also genauso und ist Geschmackssache)

Builtin-Operatoren und Funktionen

Perl stellt eine grosse Auswahl an builtin-Funktionen bereit. Einige davon haben wir bereits benutzt, z.B. 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)

Viele Operatoren können mit einem = kombiniert werden:

$a += 1;        # $a = $a + 1
$a -= 1;        # $a = $a - 1
$a .= "\n";     # $a = $a . "\n";

Dateien und I/O

Man kann eine Datei für Input oder Output mittels der 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 <> Operators 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;

Reguläre Ausdrücke

Perl bietet eine breite Unterstützung von regulären Ausdrücken, und dies wird in aller Ausführlichkeit in perlrequick, perlretut, etc. erklärt. Hier eine kurze Erklärung:

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.

Subroutinen schreiben

Subroutinen schreiben ist leicht:

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äßlich

Subroutinen können auch Werte zurückgeben:

sub square {
    my $num = shift;
    my $result = $num * $num;
    return $result;
}

Für Details über Subroutinen siehe perlsub.

OO Perl

Objektorientiertes Perl ist relativ simpel und ist mittels Referenzen implementiert, die wissen, auf welcher Art von Object sie basieren. Allerdings geht OO Perl weit über die Grenzen dieses Artikels hinaus. Man lese perlboot, perltoot, perltooc und perlobj.

Für einen Perl-Anfänger wird sich der Gebrauch von OO Perl zumeist auf den Gebrauch von Modulen von Drittanbietern beschränken, die weiter unten dokumentiert sind.

Perl-Module benutzen

Perl-Module stellen einen großen Bereich von Features zur Verfügung, die helfen, das Rad nicht neu zu erfinden, und können von CPAN (http://www.cpan.org/) heruntergeladen werden. Eine Menge populärer Module sind bereits in der Perl-Distribution enthalten.

Modul-Kategorien gehen von Textmanipulation über Netzwerk- Protokolle, Datenbankintegration bishin zu Grafik. Eine Übersicht, aufgeteilt in Kategorien, gibt es ebenfalls beim CPAN.

Wie man Module installiert, die man vom CPAN geladen hat, steht in perlmodinstall.

Wie man ein bestimmtes Modul benutzt, erfährt man über 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.

AUTOR

Kirrily "Skud" Robert <skud {at} cpan.org>

ÜbersetzerInnen, Credits

Tina Müller (pq {at} perl-community . de) Shagreen von perl-community.de

Hinweise

Inhaltliche Fehler etc. können gern geändert werden, allerdings sollte dieses Dokument möglichst die genaue Übersetzung des englischen Originals sein.

Username: