Ursprünglich konzipiert um große Mengen Text schnell zu durchsuchen und zu analysieren, wird Perl mittlerweile für nahezu alle denkbaren Zwecke eingesetzt. Am bekanntesten ist vielleicht die Verwendung als Programmiersprache für CGI1-Skripte im WWW sowie im Bereich der UNIX-Systemadministration. Aber auch für viele andere Aufgaben hat sich Perl bewährt :
um nur einige zu nennen.
Ursprünglich unter UNIX entwickelt wurde Perl mittlerweile auf praktisch jede erwähnenswerte Plattform portiert :
Neben den offiziell von der Perl-Distribution unterstützten Plattformen gibt es auch Portierungen auf verschiedene andere Plattformen, die von anderen Autoren durchgeführt wurden und u.U. nicht alle Perl-Features implementieren (z.B. unterstützt der MS-DOG Port aus naheliegenden Gründen kein fork()). Zu der großen Verbreitung von Perl hat u.a. die Tatsache beigetragen, daß viele frühere UNIX-Programmierer, die auf andere Plattformen wechselten einen möglichst großen Teil ihrer "alten Heimat" mitnehmen wollten.
Perl wurde von von Beginn an als "glue-language" entwickelt, als eine Mischung zwischen Shell- und C-Programmierung, mit Anleihen aus zahlreichen Sprachen (C, sed, awk, Englisch, Griechisch, ...) sowie verschiedenen eigenen Zutaten. Dabei ist Perl im Gegensatz zu Shell-Skripten oder C-Programmen jedoch äußerst portabel - ohne das man spezielle Definitionen (z.B. bei C #ifdef) für jede Plattform benutzen oder sich auf den ( kleinsten (hoffentlich) gemeinsamen Nenner (z.B. bei den verschiedenen Varianten der Shell auf verschiedenen Unixen) beschränken muß.
In vieler Beziehung ist Perl eine einfache Sprache - man braucht nicht zahlreiche "magische Worte" zu kennen um ein Perl-Programm zu kompilieren, man kann es einfach ausführen wie ein Shellskript. Die von Perl benutzten Typen und Strukturen sind einfach zu verstehen und zu benutzen, es werden gibt künstlichen Beschränkungen für die zu verarbeitenden Daten - Strings und Arrays können wachsen solange wie nötig (und solange der Speicher reicht) und sie sind darauf ausgelegt, trotzdem gut zu skalieren.
Obwohl Perl in vieler Hinsicht eine einfach Sprache, ist es auch eine sehr reiche Sprache, bei der es sehr viel zu lernen gibt - das ist der Preis dafür, daß die einfachen Probleme einfach und die komplexen Aufgaben überhaupt zu lösen sind.
Aufgrund seiner offenen Struktur kann Perl sehr leicht erweitert werden. Man kann Perl in andere Sprachen und andere Sprachen in Perl einbetten und sogar objekt-orientierte Bibliotheken objekt-orientiert in Perl benutzen. Durch den Mechanismus zum Modulimport können externe Definitionen so genutzt werden als wären sie in Perl eingebaut. Es gibt zahllose Erweiterungen für Perl, darunter :
Obwohl eigentlich eine Interpretersprache ist Perl eher eine Kreuzung aus Interpreter und Compiler. Zur Laufzeit wird das Perlskript vom Interpreter relativ schnell in ein internes, bytecode-ähnliches Format kompiliert. Dabei werden, wie bei jedem Compiler, zahlreiche Optimierungen durchgeführt und es erfolgen sofortige Rückmeldungen, von syntaktischen und zur compile-time erkennbaren semantischen Fehlern bis hin zu Problemen beim Einbinden von Bibliotheken. Nach dem erfolgreichen Durchlauf des Compilers wird das Kompilat an den Perl-Interpreter zur Ausführung (oder an eines der Endmodule, die Bytecode oder C-Quellcode ausgeben) weitergereicht. Obwohl das alles recht kompliziert klingt sind Compiler und Interpreter ziemlich effizient und der typische compile-run-fix Zyklus umfaßt meist nur Sekunden. Zusammen mit den vielen Möglichkeiten Perls, auf Fehler "weich" zu reagieren erlaubt diese kurze Zykluszeit echtes Rapid-Prototyping in Perl.
Einer der zahlreichen Vorteile von Perl ist die Tatsache, das man sich nicht lange bei der Vorrede (Vereinbarung von Typen, Datenstrukturen, Variablen, Subroutinen, Funktionen ) wie in anderen Programmiersprachen aufhalten muß, sondern gleich loslegen kann. Auch wenn ersteres für komplexe Probleme, die komplexe Lösungen erfordern eine gute Idee ist, so eignet sich für die vielen einfachen, alltäglichen Problem eine Programmiersprache in der man einfach und sofort sagen kann, was man tun will :
print "Hello world!\n":
und erwarten kann, daß das Programm genau das tut. Obenstehendes ist tatsächlich ein komplettes Programm und wenn man es an den Perl-Interpreter verfüttert, dann wird es
"Hello world!"auf der Konsole ausgeben. Im Gegensatz zu anderen Sprachen hat Perl kein Problem damit, wenn das Programm einfach so - ohne exit-Anweisung endet. Man kann die exit-Anweisung benutzen wenn man will , man kann einige der benutzten Variablen und Datenstrukturen und Sunroutinen deklarieren oder sich sogar zwingen, das zu tun - aber man muß es nicht, man hat die Wahl. Perl erlaubt es dem Programmier, es auf ''Die Richtige Art und Weise'' TM zu tun - wie auch immer er das definiert.
Sprachen werden von Menschen für Menschen gemacht - eine Tatsache die in der Geschichte der Informatik oftmals vergessen wurde. Perl wurde entworfen, um ähnlich wie eine natürliche Sprache zu funktionieren. Ein wichtiger Grundaspekt dabei ist die Tatsache, daß die einfachen Dinge einfach und die schwierigen Dinge möglich sein sollten. Auch wenn die ganz offensichtlich erscheint, so versagt an diesem Punkt so manche Programmiersprache.
Eine Variable ist ein Behälter für Werte, ein Behälter mit einem Namen, so daß man ihn (und seinen Inhalt) wiederfinden kann. Dabei gibt es Variablen, die nur einen Wert enthalten können, genannt Skalar, und Variablen, die mehrere Werte enthalten können, genannt Array.
In Perl werden die verschiedenen Arten von Variablen durch "magische Zeichen" markiert :
Typ | Zeichen | Beispiel | bezeichnet : |
Skalar | $ | $count | einzelner Wert (Zahl oder String) |
Array | @ | @namen | Liste von Werten, mit Nummer |
als Zugriffsschlüssel | |||
Hash | % | %anteil | Gruppe von Werte, mit String |
als Zugriffsschlüssel | |||
Subroutine | & | &convert | Aufrufbares Stück Perl-Code |
Typeglob | * | *kram | Alles was kram genannt wird |
Zuweisungen an Skalare erfolgen wie in den meisten Programmiersprachen mit dem = Operator. Einer Skalar-Variable kann dabei jeder skalare Wert zugewiesen werden : Integer, Fließpunktzahlen, Strings und sogar solche Dinge wie Referenzen auf andere Variablen oder Objekte. Es gibt verschiedene Möglichkeiten, die Werte für die Zuweisung zu erzeugen.
Wie in der UNIX Shell kann man auch hier verschiedene Quoting-Mechanismen benutzen :
Beispiele :
$antwort = 42; | # Integer |
$pi= 3.14159265; | # Fließpunktzahl |
$groesse = 6.02e12; | # wissenschaftliche Notation |
$tier = Camel; | # String |
$satz = Ich liebe mein $tier; | # String mit Interpolation |
$preis = 'Kostet $10'; | # String ohne Interpolation |
$hier = $dort; | # andere Variable |
$gesamt = $anzahl * $groesse; | # Ausdruck |
$cwd = `cwd`; | # Kommandoausgabe |
$exit = system( vi $file); | # numerischer Kommandosstatus |
$joe = new Camel Joe; | # ein Objekt |
Uninitialisierte Variablen werden bei Bedarf automatisch erzeugt. Nach dem Prinzip der minimalen Überraschung werden sie mit Nullwerten gefüllt, entweder oder 0. Je nach Verwendung werden Variablen automatisch als Strings, Zahlen oder boolsche Werte interpretiert. Dabei gelten Nullwerte als false, alle anderen Werte hingegen als true. Verschiedene Operatoren erwarten bestimmte Werte als Parameter - es heißt, sie stellen einen "skalaren Kontext" zur Verfügung. Dies kann auch genauer spezifiziert werden als numerischer Kontext, String-Kontext oder boolscher Kontext. Innerhalb sinnvoller Grenzen wandelt Perl die Daten automatisch in den erforderlichen Kontext um. Zum Beispiel bei :
$camels = '123'; |
print $camels + 1, n; |
der ursprüngliche Wert von $camels ist ein String, er wird jedoch zu einer Zahl umgewandelt um 1 dazu zu addieren und anschließend wieder in einen String umgwandelt um als solcher ausgegeben zu werden. Das Zeilenende n ist ebenfalls im String-Kontext, da es aber bereits ein String ist, entfällt die Umwandlung.
Bestimmte Arten von Variablen können mehrere Werte aufnehmen die logisch miteinander verknüpft sind : Arrays und Hashes. Sie verhalten sich in vieler Hinsicht wie Skalare : sie werden leer erzeugt wenn benötigt. Wenn ihnen ein Wert zugewiesen wird, so stellen der rechten Seite der Zuweisung einen Listen-Kontext zur Verfügung.
Man kann Arrays benutzen wenn man auf Werte nach Nummern zugreifen will und einen Hash wenn man auf Werte nach Namen zugreifen will. Zum Beispiel kann man ein Array benutzen um Monatsnummern in Monatsnamen und einen Hash um Monatsnamen nach Monatsnummern umzuwandeln.
Ein Array ist eine geordnete Liste von Skalaren, auf die über die Position des Skalars in der Liste zugegriffen wird. Diese Liste kann Zahlen, Strings oder beides enthalten (sie kann sogar Referenzen auf andere Arrays enthalten, womit man multidimensionale Arrays aufbauen kann). Um einem Array einen Listenwert zuzuweisen gruppiert man einfach die Variablen mit Klammern zusammen :
@heim = ( Sofa, Sessel, Tisch, Herd); |
Andererseits, wenn man @heim in einem Listen-Kontext benutzt, wie z.B. auf der rechten Seite einer Listen-Zuweisung, dann erhält man dieselbe Liste, die man vorher hineingeschrieben hat. Auf diese Weise kann man z.B. vier Skalarvariablen aus einem Array mit Werten belegen :
($kissen, $lift, $schreib, $platte) = @home; |
Das nennt sich Listen-Zuweisungen. Diese erfolgen natürlich parallel, so das man auch sagen kann :
($alpha, $omega) = ($omega, $alpha); |
Wie in C, so werden auch in Perl Arrays null-basiert indiziert. Der Zugriff auf einzelne Komponenten eines Arrays erfolgt durch in eckige Klammern eingeschlossene Subskripts. Man kann damit auch die Elemente eines Arrays separat zuweisen, zum Beispiel :
$heim[0] = Sofa; |
$heim[1] = Sessel; |
$heim[2] = Tisch; |
$heim[3] = Herd; |
Da Arrays geordnet sind, kann man daüber auch die Stackoperationen push und pop ausführen. Perl betrachtet das Ende eines Arrays als Spitze eines Stacks. Mit dem internen Kommando sort kann eine Liste sortiert werden.
Ein Hash ist eine ungeordnete Liste von Skalaren, auf die über einen eindeutigen Schlüsselstring zugegriffen wird. Hashes sind intern über Hashtabellen implementiert und deshalb sehr schnell. Beim Zuweisen von Werten an Elemente des Hashes muß ebenfalls der Schlüssel angegeben werden.
Beispiel :
%longday = ( Sun, Sunday, ... ); |
%longday = ( Sun => Sunday, ...); |
Mit der Funktion keys erhält man eine Liste der Schlüssel.
Filehandles dienen dem Zugriff auf Files und damit der Kommunikation mit der Umgebung. Sie werden mit der open-Funktion erzeugt. Diese Funktion benötigt zwei Parameter : das Filehandle und die zu öffnende Datei.
open(SESAM, filename); | # lesen aus existierender Datei |
open(SESAM, <filename); | # dito (explizit) |
open(SESAM, >filename); | # Datei erzeugen und schreiben |
open(SESAM, >>filename); | # an Datei anhängen |
open(SESAM, |output-pipe-command); | # Ausgabepipe erzeugen |
open(SESAM, input-pipe-command|); | # Eingabepipe erzeugen |
Zum Lesen aus dem Filehandle wird der <>-Operator benutzt, damit liefert <FILEHANDLE> immer die nächste Zeile aus der Datei. Am Dateiende liefert dieser Operator einen Nullwert als Ergebnis.
Perl kennt auch die üblichen Operatoren, für Addition +, Subtraktion -, Modulo %, Exponentation ** und so weiter. Für Strings gibt es noch den Append-Operator . und den Repeat-Operator x. Die Zuweisungsoperatoren (inklusive Autoincrement / -dekrement) entsprechen denen von C, ebenso die logischen Operatoren, die Perl außerdem, dem Sprachkonzept entsprechend, als Worte anbietet (and, not, ...). Ebenfalls von C stammen die Vergleichsoperatoren zuzüglich des Perl-Konstrukts Comparison <=> (liefert -1, 0, 1 je nach Ergebnis).
Die Filetest-Operatoren wurden der Shell nachempfunden und bieten :
Es gibt den üblichen Satz der bekannten Kontrollstrukturen, sowie ein paar Perl-Spezialitäten.
Alternativen :
Dabei ist unless ein negiertes if.
Schleifenkonstrukte :
Sowie die Konstrukte next und last als vorzeitige Abbruchmöglichkeiten.
Perl beherrscht als eingebautes Feature reguläre Ausdrücke. Dabei gibt es zwei Klassen : die Pattern-matching /foo/ und die Ersetzungs-Operatoren s/foo/bar/. In Vergleichen kann Pattern Matching mit dem Operator =~ angefordert werden. Die Details der regulären Ausdrücke würden den Rahmens dieser kurzen Einführung bei weitem sprengen, darum sei nur so viel dazu gesagt : sie entsprechen dem von grep, sed, awk, ... gewohntem.
Selbstverständlich kann man in Perl auch Subfunktionen deklarieren. Dies erfolgt mit dem sub-Schlüsselwort :
sub | myfunc { |
<BODY> | |
<return retval> | |
} |
der Aufruf der Subfunktion erfolgt dann mit myfunc (LIST);, myfunc LIST; oder &myfunc; - in letzterem Fall wird das Standardargument $_ übergeben.
Dies war ein sehr kurzer Überblick über die Sprache Perl. Ich hoffe, daß bei einigen, die sich vorher noch nicht damit beschätigt haben, das Interesse an Perl geweckt wurde. Wer Perl lernen möchte, dem kann ich als ultimatives Buch zu Perl nur das Camel Book empfehlen : Larry Wall, Tom Christiansen, Randal L. Schwartz : Programming Perl, Second Edition; O'Reilly & Associates; ISBN 1-56592-149-6.
1 Common Gateway Interface
2 Auch als "Ersetzung" bezeichnet - der Bezug auf die Variable wird durch ihren Wert ersetzt