Guest FredlHallo perl-community,
Ich bin Anfänger im Perl (überhaupt Anfänger im Programmieren) ...
Hallo Fredl,
schon verschreckt von der Diskussion? Der Code in meinem ersten Posting mag Dir umständlich vorkommen, aber es hat seine Gründe, Programme von vorneherein defensiv zu schreiben.
Als Anfänger freut man sich, wenn überhaupt was funktioniert.
Als Programmier-Halbstarker hat man das Gefühl, die Sache im Griff zu haben und möchte
coolen Code schreiben. Kürzer, eleganter und auch ein bisschen so, dass die anderen
sehen, dass kein Anfänger am Werk ist.
Mit zunehmender Routine rückt etwas anderes in den Vordergrund: Der Code muss
stabil und
wartbar sein, insbesondere wenn man ihn in anderen Projekten wiederverwenden will. Ein guter Test ist es, den eigenen Code nach 2-3 Monaten nochmal zu lesen. Wenn man nicht auf Anhieb nachvollzieht, was das Programm da tut, ist es
ineffizienter Code, denn es kostet mich jedesmal Zeit, ihn zu verstehen.
Das folgende (elegante?) 4-Zeilen-Programm ersetzt in D:\Versuch\demo.dat alle x (case-insensitive) durch Y:
open(FILE, 'D:\Versuch\demo.dat');
map { s/x/Y/ig } (@tmp = <FILE>);
open(FILE, '>D:\Versuch\demo.dat');
print FILE for @tmp;
Dabei ist einiges durch die Features von Perl wunderbar vereinfacht, z.B. die implizite Verwendung der Spezialvariable
$_, das implizite
close() beim erneuten
open() desselben Filehandles, das Weglassen des Standardmodus '<' beim ersten
open(). Die eigentliche Modifikation der Daten passiert in Zeile 2:
Die ganze Datei wird in das Array @tmp eingelesen, je eine Zeile als Array-Element. Durch die Zuweisung (=) entsteht ein sog. Lvalue, der an die
map-Funktion weitergereicht wird, die wiederum durch die Elemente von @tmp iteriert und dabei dem gerade aktuellen Element den Aliasnamen
$_ gibt. Mit diesem
$_ kann man nun einiges anstellen, alle Änderungen wirken sich sofort auf das Arrayelement aus (hier die Ersetzung:
s/x/Y/ig).
Das Abspeichern in Zeile 4 verwendet wieder die "magische"
$_-Variable, die bei
print() als Default ausgegeben wird.
Ausformuliert stünde da
open(FILE, 'D:\Versuch\demo.dat');
@tmp = <FILE>;
map { $_ =~ s/x/Y/ig } @tmp;
close(FILE);
open(FILE, '>D:\Versuch\demo.dat');
for (@tmp) {
print FILE $_;
}
close(FILE);
Warum erzähle ich das? Weil der 4-Zeilen-Code zwar
perlig, aber
unsicher ist und
unbrauchbar, wenn es nicht um diesen kleinen Spezialfall geht.
Was ist, wenn
open() scheitert?
Wie baue ich komplexere Dateiänderungen ein?
Was ist, wenn ich mal nicht nur diese eine, sondern z.B. alle .dat-Files ändern will?
Was ist, wenn ich fremden Code mitbenutze (Module, sehr ratsam), und dieser irgendwo etwas mit einem Filehandle names FILE anstellt (und damit
meine Datei ruiniert, denn mein Handle FILE ist
global)?
Nochmal der Code von oben, habs für eine andere Datei nochmal abgetippt:
open(FILE, 'D:\Versuch\demo2.dat');
map { s/x/Y/ig } (@tmp = <FILE>);
open(FILE, '>D:\Versuch\demo2.dat');
print FILE for @tnp;
Ich führe ihn aus und
Panik!, meine Datei ist leer! Der Grund ist die falsche Schreibweise von @tmp in Zeile 4. Perl erzeugt da einfach ein neues Array @tnp ohne Inhalt; Auf die falsche Schreibweise hätte Perl mich hingewiesen, hätte ich
use warnings; (oder besser auch
use strict;) an den Anfang des Skriptes gestellt (und damit komplett überflüssige Threads im Forum vermieden :).
Die Datei ist aber deswegen leer, weil der zweite
open()-Aufruf im Schreibmodus den Dateizeiger auf den Dateianfang setzt, und das wird durch
use warnings nicht verhindert, aber durch
use strict, das bereits das Kompilieren abbricht.
Also verwende ich bei Skripten, die Daten verändern, fast immer temporäre Dateien/Backups und gebe den Schritt zum Löschen/Umbenennen erst nach ausreichenden Tests frei.
Vielleicht zeigt Dir das ein wenig, warum hier über TMTOWTDI debattiert wird ...
Gruß FIFO
Editiert von FIFO: typo
Editiert von FIFO: # vor warnings/strict entfernt :)
Last edited: 2012-03-12 18:42:43 +0100 (CET)
Everyone knows that debugging is twice as hard as writing a program in the first place. So if you're as clever as you can be when you write it, how will you ever debug it? -- Brian Kernighan: "The Elements of Programming Style"