Exkurs: Perl (1) Exkurs: Perl (3) Was ist Perl? portable Scriptsprache von Larry Wall Mischung aus C, awk und sh Hauptsächlich C mit zahlreichen Notationsvarianten zur Emulation von awk => Perl gilt als hässlich "all-in-one" Tool, mit dem einfache Dinge einfach und komplexe Dinge möglich sind zahlreiche Module verfügbar Allgemeine Syntax: Perl ist casesensitiv Kommentare von ’#’ bis Zeilenende Kommandoabschluss mit ’;’ Blockbildung mit ’{ ... }’ Variablen haben als erstes Zeichen Typkennung: $bla - skalare Variable @bla - Array Variable %bla - Hash Variable (Array mit Key statt Index) Syntax von Funktionsaufrufen kennt kuriose Variante printf("%s\n", "Halloli"); printf "%s\n", "Halloli"; in (seltenen) Spezialfällen muss Argumenttrenner WhiteSpace statt Komma sein: printf(STDERR "%s\n", "Halloli"); Meinungen zu Perl: "Perl is awk with skin cancer." "Perl wird nicht mehr weiterentwickelt, weil alle Sonderzeichen aufgebraucht sind." 1 3 Exkurs: Perl (2) Exkurs: Perl (4) Programme in Scriptsprachen können nicht direkt vom OS ausgeführt werden, sondern brauchen eine Laufzeitumgebung, den Script-Interpreter. Variablen und Werte (literals) Skalare Variablen gekennzeichnet durch vorangestelltes $ keine explizite Typunterscheidung Number/String, wohl aber implizite Unterscheidung durch Kontext: $x = 1; $y = 4; # numerische Addition liefert 5 $number = $x + $y; # String-Concatenation liefert 14 $string = $x . $y; Variablendeklaration nicht erforderlich. Jede irgendwo verwendete Variable wird dem globalem Gültigkeitsbereich (Scope) zugewiesen => fehleranfällig (Vertippen): verwende besser use strict Aufruf des Perlscripts script: perl script arg1 arg2 ... arg1, ... sind Kommandozeilenargumente für script Unter Unix (oder bei Aufruf aus der Cygwin-Shell) kann script direkt ausführbar gemacht werden: als erste Zeile des Scripts einfügen: #!/usr/bin/perl Script ausführbar machen mit: chmod +x script Methode geht mit vielen Scriptsprachen (sh, perl, wish) 2 4 Dalitz DBS Perl Exkurs: Perl (5) Exkurs: Perl (7) Lokale Variablen Arrays (1) Array Variablen gekennzeichnet durch vorangestelltes @ Array Werte sind Kommalisten in runden Klammern @arr = ("bla", 10, 30); müssen deklariert werden mit my: # implizite Anlage globale Variable $x $x = 1; { # Block mit eigenem Scope my $x; # lokale Variable $x $x = 2; } # $x hat wieder Wert 1 Feldzugriff durch Index (startet mit 0) in eckigen Klammern. Da Feld skalar ist, Typkenner $ zu verwenden (verquere Logik) $arr[0] = "blabla"; höchster Index in @arr ist $#arr (-1 bei leerem Array) Anzahl Felder in @arr ist folglich $#arr + 1 # Loop über alle Werte for ($i=0; $i <= $#arr; $i++) { printf("Feld %d:%s\n", $i, $arr[$i]); } optionales Modul strict erzwingt Deklaration aller Variablen Auch globale Variablen müssen dann (im äußersten Scope) mit my deklariert werden. Modul strict wird geladen mit dem Perl-Befehl use strict; 5 Exkurs: Perl (6) 7 Exkurs: Perl (8) Arrays (2) Skalare Werte (literals) Größe von Arrays kann z.B. durch Zuweisen weiterer Feldwerte oder Manipulation von $#var verändert werden: @arr = ("a", "b"); # Größe 2 $arr[2] = "c"; # Größe 3 $#arr = -1; # entspricht @arr=(); Wer dabei Bauchschmerzen hat, kann die Perl-Funktionen pop, push, shift, unshift oder splice verwenden numeric literals werden direkt angegeben, z.B. 128 (integer), 10.28 (float), 6.02E23 (scientific notation) string literals werden gequoted mit single oder double Quotes Unterschied wie in Bourne-Shell: single Quotes kennen nur zwei Escape-Sequenzen: \’ und \\ ’Rock\’n Roll\n’ # Rock’n Roll\n double Quotes kennen mehr Escape-Sequenzen (z.B. \n) und interpolieren Variablen: $preis = ’$100’; # keine Interpolation $text = "Preis ist $preis"; # Interpolation ergibt ’Preis ist $100’ 6 Was passiert bei Erhöhung von $#var? zusätzliche Werte sind undefiniert (undef) undef ist spezieller Wert in Perl (vgl. NULL in SQL), der mit den Funktionen defined oder undef abgeprüft werden kann @arr = ("a", "b"); $#arr = 5; if (!defined($arr[3])) { printf("Feld 3 undefiniert\n"); } 8 Dalitz DBS Perl Exkurs: Perl (9) Exkurs: Perl (11) Hashes Kontrollfluss (2) Vermeidung if-Verschachtelung mit elsif: if (Bedingung1) { # Bedingung1 wahr } elsif (Bedingung2) { # Bedingung1 falsch und Bedingung2 wahr } else { # Bedingung1 und Bedingung2 falsch } Hash Variablen gekennzeichnet durch vorangestelltes % Hash Werte sind Listen von key=>value Paaren %alt = ("Klaus" => 27, "Suse" => 33); Wertzugriff durch Key in gescheiften Klammern Achtung: Typpräfix der Variablen in $ ändern! printf("Alter von Suse: %d\n", $alt{"Suse"}); Wert ist undef für nicht vorhandenen Key Bei Zuweisung je nach Bedarf "insert" oder "update" $alt{"Paul"} = 42; # Neuer Eintrag Paul=>42 $alt{"Suse"} = 35; # Ändert Suse-Eintrag Entfernen von Einträgen mit Funktion delete delete($alt{"Klaus"}); 9 logische Verknüpfung mit && und ||, Negation mit ! Perl unterstützt auch verbale Variante and, or und not Wie C wertet Perl nur minimal nötige Bedingungen aus => kann z.T. wie in Shell-Scripten genutzt werden: open(IFH, $INFILE) || die("Cannot open $INFILE\n"); Unterschied zur Shell: kein Kommandoblock {...} zulässig Exkurs: Perl (10) Exkurs: Perl (12) Kontrollfluss (1) Operatoren 11 Kontrollstrukturen wie in C if - bedingte Verzweigung (Variante: unless) for - Loop mit Zählvariable while - Loop mit Abbruchbedingung (Variante: until) Unterschied zu C: danach kein Einzelkommando zulässig, sondern nur Block mit geschweiften Klammern Unterschied zu C bei Sprunganweisungen für for und while: break in C enspricht last in Perl continue in C enspricht next in Perl betrifft defaultmässig innere Schleife; optionales Label möglich um bei Verschchtelungen aus bestimmter Schleife zu springen Operator Bedeutung + - * / % . = += -= *= .= ++ -== != < <= > >= eq ne lt le gt ge -e -r -w -d arithmetische Operatoren Stringconcatenation Zuweisungsoperatoren Modifikationsoperatoren numerische Vergleiche String Vergleiche Filetesting-Operatoren modelliert nach test-Operator der Shell Achtung: Verwendung von == statt eq ist häufigster Programmierfehler in Perl 10 12 Dalitz DBS Perl Exkurs: Perl (13) Exkurs: Perl (15) Funktionen Funktionen (?) für Pattern-Matching Als strukturierte Programmiersprache unterstützt Perl das Abstraktionsmittel Funktionen. In Kombination mit =~ ("Binding-Operator") Operatoren Binding-Operator soll awk-Syntax emulieren Ursache historisch bedingt: awk sollte leicht nach Perl portierbar sein eingebaute Funktionen fester Bestandteil der Perl-Basisimplementierung sind meistens "überladen", so dass sie bei Aufruf ohne Argumente die eingebaute Perl-Variable $_ als Argument nehmen benutzerdefinierte Funktionen werden im Perl-Script implementiert und aufgerufen Module mit Funktionspaketen in beliebiger Sprache (z.B. Perl, C, Fortran) implementiert im Script ladbar mittels use. Suchpfad für Module ist @INC Laufzeitverhalten merkwürdig (vgl. demo4.pl): $str =~ m/regexp/ Vergleich mit regulärem Ausdruck. m kann auch weggelasssen werden (!) zwecks Emulation awk-Syntax $str =~ s/from/to/ ersetzt in $str auf Basis regulärer Ausdrücke. Identisch zu Kommando des Unix-Programms sed $str =~ tr/charlist1/charlist2/ ersetzt in $str einzelne Zeichen Vergleichbar mit Unix-Programms tr Existenzprüfung Modul schon beim Interpreter-Schritt Laden erst an Code-Stelle zur Laufzeit 13 15 Exkurs: Perl (14) Exkurs: Perl (16) String-Funktionen Reguläre Ausdrücke $int = length($str) Stringlänge (Anzahl Zeichen) Symbol Bedeutung $str = sprintf("Anzahl: %d\n", 3) wie printf, nur dass Ergebnis als String zurückgegeben wird . + * ein beliebiges Zeichen Quantifier: mindestens einmal (+) bzw. belibig oft (*) Gruppierung Oder-Alternative von Gruppen Oder Alternative einzelner Zeichen durch führendes ˆ negiert String-Anfang (ˆ) bzw. - Ende ($) $str = substr($str, $offset, $length) Extraktion Teilstring; Offset beginnt bei 0 () | [] @arr = split(’regexp’, $str) Zerlegung aufgrund Trennzeichen (beliebige "regular Expression") als Begrenzer von regexp neben ’..’ auch /../ zulässig Zerlegung in Einzelbuchstaben: split(’’, $str) ˆ $ Beispiel: regulärer Ausdruck für PLZ und Ort: ^[0-9][0-9][0-9][0-9][0-9] [a-zA-Z\- ]+$ $str = join($sep, @arr) fügt Felder mit Trenner $sep zusammen 14 16 Dalitz DBS Perl Exkurs: Perl (17) Exkurs: Perl (19) IO-Funktionen Kommandozeilenargumente Input und Output ist immer an Filehandle gebunden Perl-Filehandle haben keinen Variablentyp-Präfix (!) vordefinierte Filehandle sind STDIN, STDOUT und STDERR $bool = open(FH, "<filename") öffnet Datei zum Lesen; > zum Schreiben, >> zum Anhängen close(FH) schließt Datei (in Perl meist nicht nötig) print(FH $str) printf(FH "Anzahl: %d\n", 5) (formatierte) Ausgabe nach FH; wenn FH weggelassen: STDOUT Achtung: nach Parameter FH kein Komma (!!) $str = <FH> Einlesen Zeile (incl. \n) von FH 17 stehen in eingebauter Variable @ARGV Beispiel für Auswertung Kommandozeilenargumente: for ($i=0; $i<=$#ARGV; $i++) { if ($ARGV[$i] eq "-a") { # einfache Option $opta = 1; } if ($ARGV[$i] eq "-p") { # Option mit Folgeargument $i++; $optpaper = $ARGV[$i]; } else { # Fehlerbehandlung unzulässige Option } } Exkurs: Perl (18) Exkurs: Perl (20) Beispiel für File-Verarbeitung: Benutzerdefinierte Funktionen # Datei öffnen open(IFH, $INFILE) || die("Cannot open $INFILE\n"); 19 definiert mittels sub Prototypen seit Perl 5 auch möglich # zeilenweises Abarbeiten while ($line = <IFH>) { Argumentübergabe (Call by Value) im Array @_ Call by Reference seit Perl 5 ebenfalls möglich # take care of embedded EPS images if ($line =~ /^\%\%BeginDocument:/) { $insideepsf++; } if (($line =~ /^\%\%EndDocument/) && ($insideepsf>0)) { $insideepsf--; } Rückgabe Ergebnis mittels return # count pages if (($line =~ /^\%\%Page:/) && ($insideepsf==0)) { $N++; } } # Ausgabe Gesamtzahl Seiten print("Postscriptfile $INFILE hat $N Seiten\n"); 18 # ($s3) concat ($s1, $s2) # - hängt zwei Strings aneinander sub concat { my $s1=$_[0]; my $s2=$_[1]; my $s3; $s3 = $s1 . $s2; return $s3; } 20 Dalitz DBS Perl