200 likes | 283 Views
Die Skriptsprache Perl (2). Wolfgang Friebel DESY Zeuthen. Anmerkungen zu Teil 1. Wichtige Zeichen: <br> t e 33 x1b u l Wichtige Vars: $_ $| $. $? $! $$ $< $0 $& $` $’ @ARGV @INC %ENV Bitoperatoren: & | ^ ~ (and, or, xor, not) defined: if (defined $a) ...
E N D
Die Skriptsprache Perl (2) Wolfgang Friebel DESY Zeuthen
Anmerkungen zu Teil 1 • Wichtige Zeichen: \n \t \e \033 \x1b \u \l • Wichtige Vars: $_ $| $. $? $! $$ $< $0 $& $` $’ @ARGV @INC %ENV • Bitoperatoren: & | ^ ~ (and, or, xor, not) • defined: if (defined $a) ... if (defined &sub) ... • undef: undef $a; undef %h; undef ⊂ $a = undef;
3. Programmfluß • Einfaches Statement: durch ; begrenzt Leerraum (‘ ‘, \t, \n) wird außerhalb von Strings ignoriert (Ausnahme: Schlüsselwörter wie z.B. print) • Kommentar: eingeleitet mit #, gilt bis Zeilenende • Block: in { } eingeschlossene Statements zählen genauso wie einfaches Statement • Subroutine: sub {statements;} Subroutinen heißen auch Funktionen, kein Unterschied können Argumente bekommen und Werte zurückgeben
Gültigkeitsbereich von Variablen • Alle Variablen sind global (im package main) $a ist identisch mit $main::a damit auch in jeder Subroutine sichtbar • Package kann geändert werden (siehe später) • Werte globaler Variablen können versteckt werden local $a # gilt in Block, Subroutine, File, eval für magische Variablen einzige Möglichkeit Variable erhält mit local nur neuen Wert, ist noch global
Lexikalische Variablen mit my • Mit my definiert man Variablen, die nur im aktuellen Block (oder File, eval, sub) existieren • Private Variablen mit my sind wirklich lokal my $a = 1; my ($b, $c); my %hash; • Analog zu auto Variablen in C • Überwiegende Verwendung von my ist gute Praxis
Bedingte Ausführung • Falsche und wahre (logische) Ausdrücke falsch: 0, leerer String, Array, Hash, alles andere ist wahr • Verknüpfung logischer Ausdrücke mit and/or/not bzw. &&/||/! and/or/not hat sehr niedrige Priorität, ist meist besser • Abbruch der Auswertung wenn Wahrheiswert feststeht, wird nicht weiter ausgewertet $a && print ”1”; # print nur wenn $a wahr $a || print ”2”; # print nur wenn $a falsch
if then else • Syntax: if ( Bedingung ) {Statements;} if ( Bedingung ) {Statements;} else {Statements;} if ( Bedingung ) {Statements;} elsif ( Bedingung ) {Statements;} else {Statements;}
Andere bedingte Operatoren • Alternative zu if-elsif-else, Syntax: Statement if Bedingung; Statement unless Bedingung; wird verwendet, wo Statement wichtiger als Bedingung • an C angelehnter if-then-else Operator Bedingung ? Wahr-statement : False-statement; wird gern in print Statements verwendet
Beispiele • Beispiele für Einsatz der verschiedenen Konstrukte open(FILE,”hallo.pl”) or die ”open failed\n” print ”Debug: Wert von a:$a\n” if $debug; if (@ARGV) { print $#ARGV+1, ”Args\n”; } else { print ”Programm ohne Argumente\n”; } print $cat, ” Katze”, $cat == 1 ? ”” : ”n”;
File Testoperatoren • Nicht nur Testoperatoren für Strings und Zahlen: etwa 30 Testoperatoren für Files • Syntax: -x ”filename” wobei x die Testart ist • wichtigste Teste: -r lesbar -e existiert -f file -x ausführbar -s Länge > 0 -d Verzeichnis -w schreibbar -B Binärfile -l Link • Nachfolgende Teste auf gleiches File benutzen _ statt Filename (Geschwindigkeit): exit if -B _;
Switch • Es gibt kein Switch Statement Nachbildung: siehe z.B perldoc -q switch Bei Verwendung von last (Äquivalent zu break in C): $_ = <STDIN>; { if (/^a/) {$alpha++; last;} if (/^b/) {$beta++; last;} if (/^d/) {$debug=1; last;} }
Schleifen • In der Reihenfolge der Beliebtheit: for $i (@array) {$anzahl{$i}++;} for $i (1 .. 10) {print ”7*$i=”,7*$i,”\n”;} while ($eps > 0.01) { .. iteriere weiter .. } for ($i=1; $i<101; $i++) {$gauss += $i;} while (1) {$_=<STDIN>; last if /^quit/;} for (;;;) {print ”Hier hilft nur CTRL-C\n”;} do { Statements; } while ( Bedingung; );
Schleifenkontrolle • Den Schleifen (wie auch jedem anderen Statement) kann ein Label gegeben werden: LINE: for $line (@lines) {print $line;} • Änderung des Schleifendurchlaufs mit last; oder last LINE; # verlasse Schleife next; oder next LINE; # nächster Zyklus redo; oder redo LINE if ...; # wiederhole • last/next/redo auch in normalen Blöcken möglich
Schleifen mit map und grep • Funktionen map und grep stellen implizit Loops dar @sizes = map { -s $_ } @files; ist äquivalent zu for ( @files ) { push @sizes, -s $_; } • grep testet den Block als Ausdruck und übernimmt die Elemente des Feldes, für die Ausdruck wahr @mylines = grep { /my/ } @lines; ist äquivalent zu for (@lines) { push @mylines, $_ if /my/; }
Schleifen und I/O • Aufruf von perl mit Optionen -a, -i, -n, -p erzeugt implizite Schleife über @ARGV (Filenamen) • Einlesen von Files typisch mit open FILE, $file or die ”$file: $!\n” while (<FILE>) { $line = $_; } close FILE; • Elegantere Möglichkeit: while (<>) { $line = $_; } dann wird entweder von @ARGV oder STDIN gelesen
Goto • Ist vorhanden • selbst computed goto ist implementiert!!! • habe ich noch nie gebraucht • sollte sicher im Interesse guten Stils vermieden werden • daher schnell weiter ...
Subroutinen • Deklaration/Definition: sub name {Statements;} • Deklaration (vor Definition): sub name; • Aufruf: name(Parameterliste); name Parameterliste; #name ist deklariert &name; oder name();# falls name nicht deklariert • Definition mit Prototypen möglich, nicht behandelt • Zahl der Parameter wird durch Aufruf festgelegt, nicht in Definition (Übereinstimmung von Aufruf und Definition ist Sache des Authors)
Parameterübergabe • Aufruf mit Liste (Parameterliste) • Subroutine werden Werte in @_ übergeben • Call by Reference Änderung von @_ ändert Werte im rufenden Programm! • Separat übergebene Felder sind in @_ vereint • Rückgabewert ist Wert der letzten Anweisung • Kann auch durch return wert; festgelegt werden • als Rückgabewert ist Variable oder Liste möglich
Ausführungskontext • Aufruf einer Funktion entscheidet über Kontext kann je nach Kontext unterschiedliche Dinge tun $a = @feld # linke Seite ist skalar, $a => $#feld @a = @feld # linke Seite ist Feld, @a => @feld • Viele Funktionen haben skalaren und Listkontext $datum=gmtime(); # Thu Jan 20 10:38:17 2000 @datum=gmtime(); # (17,38,10,20,0,100,4,19,0) • Listkontext ist Standard, Skalarkontext kann erzwungen werden: print scalar gmtime(),”\n”;
Hausaufgaben • Überprüfe, ob 0, ‘0’, “0”, ‘00’, ‘’, “”, ‘ ‘, () Null bzw. falsch sind • Wie sind die Vorrangregeln für Operatoren? (Camel S.76) • Wo soll man Leerzeichen und Leerzeilen im Programm pla(t)zieren? (perldoc perlstyle) • Schreibe ein Programm, das den vorzeitigen Abbruch bei logischen Operatoren ausnutzt (z.B. Test auf eins von 3 Betriebssystemen oder Abbruch) • Schreibe ein Programm, das Wortlisten von Files ausgibt • Wozu kann man perl -n oder perl -p gut gebrauchen? • Suche weitere kontextabhängige Funktionen