Impressum
Frank Seitz Industriestraße 31 22880 Wedel E-Mail: fs Telefon: +49 (0)4103 180301 Fax: +49 (0)4103 180302 Kurzprofil CPAN-Module Vuvuzela-Time KategorienAbonnieren |
Donnerstag, 20. Mai 2010Perl: POD als Programm-HilfetextDas Core-Modul Pod::Usage kann einen Programm-Hilfetext aus der eingebetteten POD-Dokumentation generieren. Es geht auch einfacher:
produziert auf STDOUT NAME
myprog - a simple program
LICENSE
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
Donnerstag, 25. März 2010Perl: Plus / Minus UnendlichPerl kennt mehrere Zeichenketten, die - numerisch interpretiert - plus und minus Unendlich bedeuten.
Beispiel: Maximum ermitteln
Aber Achtung: Diese besonderen Werte sind nicht sonderlich gut dokumentiert und scheinen bei einigen Windows-Ports nicht zu funktionieren. Siehe: http://reneeb-perlblog.blogspot.com/2010/03/unendliches-perl.html Donnerstag, 18. März 2010Perl: Dirhandles objektorientiertAnalog zu lexikalischen Filehandles besitzt Perl lexikalische Dirhandles. Eine Dirhandle ist ein Iterator über einem Verzeichnis. Die Operationen auf Dirhandles lassen sich objektorientiert kapseln. Hier eine entsprechende Klasse Dirhandle mit drei Methoden: new() (Directory öffnen), close() (Directory schließen) und next() (nächster Directory-Eintrag): Beispiel: Gib alle Einträge des Verzeichnisses $dir auf STDOUT aus 1 use Dirhandle; 2 3 my $dh = Dirhandle->new($dir); 4 while (my $entry = $dh->next) { 5 say $entry; 6 } 7 $dh->close; Das Dirhandle-Objekt $dh kann wie jede normale Dirhandle an die Perl-Builtins readdir(), telldir(), seekdir(), rewinddir(), closedir() übergeben werden. Dienstag, 16. März 2010Perl: Filehandles objektorientiertMit lexikalischen Filehandles ist es in Perl leicht möglich, File-I/O objektorientiert zu kapseln. Hier zur Veranschaulichung eine Klasse Filehandle mit drei Methoden: new() (Datei öffnen), close() (Datei schließen) und slurp() (Datei komplett einlesen): Beispiel: Lies eine Datei komplett ein und gib sie auf STDOUT aus 1 use Filehandle; 2 3 my $fh = Filehandle->new('<',$file); 4 print $fh->slurp; 5 $fh->close; Der Clou: Die Filehandle $fh kann unabhängig von der Klasse wie jede andere Perl-Filehandle benutzt werden, z.B. mit dem Diamant-Operator <> oder jeder anderen Filehandle-Operation wie read(), write() usw. Obiges Programm lässt sich also auch so implementieren: 1 use Filehandle; 2 3 my $fh = Filehandle->new('<',$file); 4 while (<$fh>) { 5 print; 6 } 7 $fh->close; Freitag, 5. März 2010Perl: Crash bei Umleitung von STDERR auf Skalare VariableIch weiß nicht, wann Perl mir mal abgestürzt ist, aber jetzt bin ich auf einen Fall gestoßen:
$ ./test.pl Segmentation fault Perl-Version (andere habe ich nicht probiert): $ perl -v This is perl, v5.10.1 (*) built for i686-linux VariationenWenn $s kein In-Memory File ist, geht es. Bei $s =~ s/./xx/; geht es (ohne g Modifier). Bei $s =~ s/./x/g; geht es (der String wird nicht länger). Schließen von STDERR vor dem s/// ändert nichts. Freitag, 5. Februar 2010Syntax-Highlighting mit perltidyPerltidy stellt die Syntax von Perl-Code farbig und mit Fontattributen wie kursiv und fett dar, wenn man den Code mit Option -html nach HTML wandelt. Ich nutze dieses Feature, um lesbareren Perl-Code für mein Blog zu generieren. Für die Einbettung des generierten HTML-Codes in eigene HTML-Seiten sind allerdings kleinere Sonderbehandlungen nötig. Anpassung der Stylesheet-DefinitionenPerltidy generiert mit $ perltidy -html -ss >FILE.css eine Stylesheet-Datei, die die Definitionen der CSS-Klassen für die Syntaxelemente enthält und in die eigenen HTML-Seiten eingebunden werden kann: /* default style sheet generated by perltidy */ body {background: #FFFFFF; color: #000000} pre { color: #000000; background: #FFFFFF; font-family: courier; } .c { color: #228B22;} /* comment */ .cm { color: #000000;} /* comma */ .co { color: #000000;} /* colon */ .h { color: #CD5555; font-weight:bold;} /* here-doc-target */ .hh { color: #CD5555; font-style:italic;} /* here-doc-text */ .i { color: #00688B;} /* identifier */ .j { color: #CD5555; font-weight:bold;} /* label */ .k { color: #8B008B; font-weight:bold;} /* keyword */ .m { color: #FF0000; font-weight:bold;} /* subroutine */ .n { color: #B452CD;} /* numeric */ .p { color: #000000;} /* paren */ .pd { color: #228B22; font-style:italic;} /* pod-text */ .pu { color: #000000;} /* punctuation */ .q { color: #CD5555;} /* quote */ .s { color: #000000;} /* structure */ .sc { color: #000000;} /* semicolon */ .v { color: #B452CD;} /* v-string */ .w { color: #000000;} /* bareword */ Anpassung 1Die CSS-Definitionen für <body> und <pre> am Anfang sollten im Falle einer Einbettung nicht vorkommen, da diese an anderer Stelle definiert sind. Sie lassen sich mit grep wegfiltern. $ perltidy -html -ss | grep '^\.' Anpassung 2Die Namen der CSS-Klassen bestehen aus ein oder zwei Buchstaben, was zu Nameclashes führen kann. Dies verbessere ich, indem ich dem Klassennamen einen Präfix voranstelle. Ich wähle "pt-". $ perltidy -html -ss | grep '^\.' | sed -e 's/^\./.pt-/' Resultierende CSS-Datei.pt-c { color: #228B22;} /* comment */ .pt-cm { color: #000000;} /* comma */ .pt-co { color: #000000;} /* colon */ .pt-h { color: #CD5555; font-weight:bold;} /* here-doc-target */ .pt-hh { color: #CD5555; font-style:italic;} /* here-doc-text */ .pt-i { color: #00688B;} /* identifier */ .pt-j { color: #CD5555; font-weight:bold;} /* label */ .pt-k { color: #8B008B; font-weight:bold;} /* keyword */ .pt-m { color: #FF0000; font-weight:bold;} /* subroutine */ .pt-n { color: #B452CD;} /* numeric */ .pt-p { color: #000000;} /* paren */ .pt-pd { color: #228B22; font-style:italic;} /* pod-text */ .pt-pu { color: #000000;} /* punctuation */ .pt-q { color: #CD5555;} /* quote */ .pt-s { color: #000000;} /* structure */ .pt-sc { color: #000000;} /* semicolon */ .pt-v { color: #B452CD;} /* v-string */ .pt-w { color: #000000;} /* bareword */ Anpassung des HTML-CodesPerltidy erzeugt mit $ perltidy -html -pre <FILE >FILE.html eine Quelltext-Darstellung in HTML. Diese kann in die eigene Seite eingebunden werden. Anpassung 1Der HTML-Code ist in ein <pre> ohne Klassenanabe eingefasst. Das CSS-Layout dieses <pre> lässt sich also nicht gezielt anpassen. Am besten filtert man es weg und setzt den HTML-Code in ein eigenes <pre>. $ perltidy -html -pre <FILE | egrep -v '^</?pre>' Anpassung 2Die CSS-Klassennamen müssen an die oben gewählten Namen in der Stylesheet-Datei angepasst werden. $ perltidy -html -pre | egrep -v '^</?pre>' | sed -e 's/class="/class="pt-/g' Resultierender HTML-CodeAus print "Hello world!\n"; wird im HTML-Output (Umbruch hinzugefügt) <span class="pt-k">print</span> <span class="pt-q"> "Hello world!\n"</span><span class="pt-sc">;</span> und im Browser print "Hello world!\n"; Perl: Effizient Zeichen zählenIst eine FAQ (s. perldoc -q occurrences), aber ich vergesse immer die genaue Syntax, da ich tr/// selten nutze und es mehrere Funktionen in sich vereint: $n = $str =~ tr/\n//; $n ist in diesem Fall die Anzahl der Zeilenumbrüche in $str. Mittwoch, 27. Januar 2010Perl: Gleitkomma-Zahlen ausgeben wie sie sindVielleicht trivial, aber mir war die Antwort bislang nicht klar: Wie gebe ich eine Gleitkomma-Zahl aus, ohne dass Stellen wegfallen oder überflüssige Nullen am Ende erscheinen? Bei der Ausgabe von Gleitkommazahlen habe ich bislang automatisch zu printf/sprintf und %f gegriffen, aber das Format-Element %f formatiert die Zahlen ja immer auf eine feste Anzahl an Stellen und rundet auf die letzte Stelle. Z.B. my $x = 0.123456789; printf "%f",$x; ergibt 0.123457 (%f formatiert/rundet per Default auf 6 Nachkommastellen) Natürlich kann ich die Anzahl der Stellen groß wählen, aber dann bekomme ich u.U. zusätzliche Stellen, wenn die betreffende Zahl binär nur näherungsweise dargestellt werden kann: my $x = 0.123456789; printf "%.20f",$x; ergibt 0.12345678899999999734 Andererseits erhalte ich am Ende überflüssige Nullen bei Zahlen, die dezimal weniger als die vorgegebenen Stellen besitzen: my $x = 0.5; printf "%.20f",$x; ergibt 0.50000000000000000000 Was tun? Die Lösung ist (anscheinend) einfach: Ich gebe die Zahl nicht als Zahl sondern als String aus! D.h. im Falle von printf/sprintf mit Format-Element %s! Damit erhalte ich, was ich will. Die Zahl mit allen Stellen und nicht mehr my $x = 0.123456789; printf "%s",$x; 0.123456789 und ohne überflüssige Nullen my $x = 0.5; printf "%s",$x; 0.5 Bei näherer Überlegung leuchtet das ein, da Perl intern neben der (binären) numerischen Repräsentation eine Stringrepräsentation des Werts speichert, welche anfänglich genau der Zeichenfolge bei der Zuweisung entspricht. Schlussfolgerung: Programme, die nicht rechnen, sondern Gleitkommazahlen nur einlesen und wieder ausgeben, sollten, um Verfälschungen auszuschließen, diese bei der Ausgabe grundsätzlich als Strings und nicht als Zahlen behandeln. Mittwoch, 20. Januar 2010Perl-Operationen auf SymlinksFür den Umgang mit Symlinks stellt Perl eine Reihe von Builtins zur Verfügung, die nicht unbedingt offensichtlich sind. Hier eine kurze Übersicht:
Dienstag, 19. Januar 2010Liste der zusätzlich installierten Perl-ModuleWie ermittele ich, welche Perl-Module über das Grundsystem hinaus installiert wurden? Die Antwort liefert das Kommando: $ perldoc perllocal Das Ergebnis ist ein formatiertes POD-Dokument, das die Installationshistorie aller per make install oder ./Build install installierten Module aufführt. Das Dokument wird mit der Installation des ersten Moduls angelegt. Unmittelbar nach Installation des Core-Systems ist es noch nicht vorhanden, da noch kein zusätzliches Modul installiert wurde. Mit jeder Modul-Installation wird ein Eintrag am Ende hinzugefügt. Wird ein Modul mehrfach installiert, taucht es mehrfach auf. ProgrammLiefere die Namen der zusätzlich installierten Module, alphabetisch sortiert, ohne Doubletten: 1 #!/usr/bin/env perl 2 3 use strict; 4 use warnings; 5 6 my %mod; 7 my $cmd = 'perldoc -u perllocal'; 8 open(my $fh,'-|',$cmd) or die "ERROR: open failed ($!)"; 9 while (<$fh>) { 10 if (/^=head2.*\|(.*)>/) { 11 $mod{$1} = 1; 12 } 13 } 14 close($fh) or die qq|ERROR: Command failed: "$cmd" (Exit Code: $?)\n|; 15 16 for my $mod (sort keys %mod) { 17 print "$mod\n"; 18 } 19 20 # eof Dienstag, 12. Januar 2010Speicherbedarf von Perl-VariablenDer Speicherbedarf von einzelnen Perl-Variablen und komplexeren Datenstrukturen lässt sich mit Devel::Size ermitteln. Hier die Werte für Perl 5.10 auf einem 32-Bit System. (Eine andere Betrachtung - Messung des verbrauchten virtuellen Speichers bei großen Datenstrukturen - hat Peter J. Holzer angestellt: http://www.hjp.at/programming/perl/memory/) Skalare
Perl alloziert bei Strings jeweils 4 Bytes im Voraus, vermutlich um jedes UTF-8 Zeichen speichern zu können. Obige Berechnung geht von 1-Byte-Zeichen aus. Enthält der String UTF-8 Zeichen mit 2, 3 oder 4 Byte, vergrößert sich der Platzbedarf entsprechend. Arrays
Perl vergrößert ein Array schrittweise auf 4, 8, 16, 32, 64, ... Elemente. D.h. wird das 4. Element zugewiesen, vergößert Perl intern schon auf 8 Elemente usw. Für jedes Element alloziert Perl einen Pointer (4 Bytes). Die angegebene Größe ist der Netto-Speicherbedarf des Array, d.h. der Speicherbedarf der (skalaren) Werte kommt noch hinzu. Hashes
Perl vergrößert einen Hash schrittweise auf 8, 16, 32, 64, ... Elemente. D.h. wird das 8. Element zugewiesen, vergößert Perl intern auf 16 Elemente usw. Für jeden Key alloziert Perl vorab einen Pointer (4 Bytes). Zusätzlich kommt mit zunehmender Anzahl Buckets ein wachsender Overhead von 9, 10, 11, ... Bytes je Key hinzu. Die Größe des Key geht auch mit ein. Bei der Messung unten ist der Key der String "EintragNNNN", also 11 Zeichen lang. Die angegebene Größe ist der Netto-Speicherbedarf des Hash, d.h. der Speicherbedarf der Werte kommt noch hinzu. MessungPerl Version: 5.010000 Skalar ohne Wert: 16 Bytes Referenz: 16 Bytes Integer: 16 Bytes Float: 24 Bytes String - leer: 36 Bytes String - 1 1-Byte Zeichen: 36 Bytes (Diff: 0) String - 2 1-Byte Zeichen: 36 Bytes (Diff: 0) String - 3 1-Byte Zeichen: 36 Bytes (Diff: 0) String - 4 1-Byte Zeichen: 40 Bytes (Diff: 4) String - 5 1-Byte Zeichen: 40 Bytes (Diff: 0) String - 6 1-Byte Zeichen: 40 Bytes (Diff: 0) String - 7 1-Byte Zeichen: 40 Bytes (Diff: 0) String - 8 1-Byte Zeichen: 44 Bytes (Diff: 4) String - 9 1-Byte Zeichen: 44 Bytes (Diff: 0) String - 10 1-Byte Zeichen: 44 Bytes (Diff: 0) String - 11 1-Byte Zeichen: 44 Bytes (Diff: 0) String - 12 1-Byte Zeichen: 48 Bytes (Diff: 4) String - 16 1-Byte Zeichen: 52 Bytes (Diff: 4) String - 20 1-Byte Zeichen: 56 Bytes (Diff: 4) Array - leer: 100 Bytes Array - 4 Elemente: 116 Bytes (Diff: 16) - 29.0 Bytes/Key Array - 8 Elemente: 148 Bytes (Diff: 32) - 18.5 Bytes/Key Array - 16 Elemente: 212 Bytes (Diff: 64) - 13.2 Bytes/Key Array - 32 Elemente: 340 Bytes (Diff: 128) - 10.6 Bytes/Key Array - 64 Elemente: 596 Bytes (Diff: 256) - 9.3 Bytes/Key Hash - leer: 76 Bytes Hash - 4 Keys: 208 Bytes (Diff: 132) - 52.0 Bytes/Key Hash - 8 Keys: 372 Bytes (Diff: 164) - 46.5 Bytes/Key Hash - 16 Keys: 636 Bytes (Diff: 264) - 39.8 Bytes/Key Hash - 32 Keys: 1228 Bytes (Diff: 592) - 38.4 Bytes/Key Hash - 64 Keys: 2412 Bytes (Diff: 1184) - 37.7 Bytes/Key Hash - 128 Keys: 4780 Bytes (Diff: 2368) - 37.3 Bytes/Key Hash - 256 Keys: 10540 Bytes (Diff: 5760) - 41.2 Bytes/Key Hash - 512 Keys: 18988 Bytes (Diff: 8448) - 37.1 Bytes/Key Hash - 1024 Keys: 42028 Bytes (Diff: 23040) - 41.0 Bytes/Key Programm1 #!/usr/bin/env perl 2 3 use strict; 4 use warnings; 5 6 use Devel::Size; 7 8 print "Perl Version: $]\n"; 9 10 my $s1; 11 print 'Skalar ohne Wert: ',Devel::Size::size(\$s1)," Bytes\n"; 12 13 my $s2 = \$s1; 14 print 'Referenz: ',Devel::Size::size(\$s2)," Bytes\n"; 15 16 my $s3 = 4711; 17 print 'Integer: ',Devel::Size::size(\$s3)," Bytes\n"; 18 19 my $s4 = 1234.567; 20 print 'Float: ',Devel::Size::size(\$s4)," Bytes\n"; 21 22 my $s5 = ''; 23 my $nLast = Devel::Size::size(\$s5); 24 print "String - leer: $nLast Bytes\n"; 25 26 for my $i (1..12,16,20) { 27 $s5 = 'x'x$i; 28 my $n = Devel::Size::size(\$s5); 29 print "String - $i 1-Byte Zeichen: $n Bytes (Diff: ",$n-$nLast,")\n"; 30 $nLast = $n; 31 } 32 33 my @a1; 34 $nLast = Devel::Size::size(\@a1); 35 print "Array - leer: $nLast Bytes\n"; 36 37 for my $i (4,8,16,32,64) { 38 my @a2 = (1..$i); 39 my $n = Devel::Size::size(\@a2); 40 my $diff = $n-$nLast; 41 my $avg = $n/$i; 42 printf "Array - $i Elemente: $n Bytes (Diff: $diff) - %.1f Bytes/Key\n",$avg; 43 $nLast = $n; 44 } 45 46 my %h1; 47 $nLast = Devel::Size::size(\%h1); 48 print "Hash - leer: $nLast Bytes\n"; 49 50 for my $i (4,8,16,32,64,128,256,512,1024) { 51 my %h2; 52 for (my $j = 1; $j <= $i; $j++) { 53 $h2{sprintf 'Eintrag%04d',$j} = $j; 54 } 55 # @h2{(1..$i)} = (1..$i); 56 my $n = Devel::Size::size(\%h2); 57 my $diff = $n-$nLast; 58 my $avg = $n/$i; 59 printf "Hash - $i Keys: $n Bytes (Diff: $diff) - %.1f Bytes/Key\n",$avg; 60 $nLast = $n; 61 } 62 63 # eof Donnerstag, 7. Januar 2010Perl-Interpreter über Shebang-Zeile suchen#!/usr/bin/env perl Mit dieser Shebang-Zeile wird der Perl-Interpreter über die Environment-Variable
(Seite 1 von 1, insgesamt 12 Einträge)
|
Kalender
SucheStatistikenLetzter Artikel:
31.05.2010 16:41 40 Artikel insgesamt
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||