In der Beschreibung der Funktion Perl -i[extension]
bei http://perldoc.perl.org/perlrun.html, Code, der als „äquivalent“ zu verwenden perl -pi.orig ...
gegeben ist wesentlich identisch mit dem folgenden Programm:Wie ist Perl * wirklich * implementiert?
#!/usr/bin/perl
use strict;
use warnings;
my $extension = '.orig';
my $oldargv = '';
my $backup;
LINE: while (<>) {
if ($ARGV ne $oldargv) {
if ($extension !~ /\*/) {
$backup = $ARGV . $extension;
} else {
($backup = $extension) =~ s/\*/$ARGV/g;
}
rename($ARGV, $backup);
open(ARGVOUT, ">$ARGV");
select(ARGVOUT);
$oldargv = $ARGV;
}
# Don't change anything; just copy.
}
continue {
print;
}
select(STDOUT);
Dies funktioniert gut, wenn $extension eq '.orig'
; Perl definiert jedoch -i
ohne Erweiterung (also für $extension eq ''
). Perl definiertes Verhalten ist die Datei an seinem Platz zu bearbeiten, ohne Backup-Datei erstellt:
Wenn keine Erweiterung geliefert wird, und das System unterstützt, die ursprüngliche Datei ohne Namen offen gehalten wird, während der Ausgang umgeleitet wird zu einer neue Datei mit dem ursprünglichen Dateinamen. Wenn Perl sauber oder nicht existiert, wird die ursprüngliche Datei nicht verknüpft.
Vielleicht unterstützt mein System (Mac OS X Yosemite 10.10.3) es nicht.
Wenn ich $extension = ''
in diesem Programm gesetzt, dann wird der Code für die Dateien, die kleiner als einen Block von STDIN (4096 Bytes in AcivePerl 5.10, aber 8192 Bytes von ActivePerl 5.16) gut funktionieren, aber es wird nicht Arbeit für Dateien größer als ein Block.
Es sieht für mich, dass auf meinem System, wenn $ARGV
und $backup
den gleichen Wert haben (was sie, wenn $extension eq ''
, dann ist der open(ARGVOUT, ">$ARGV")
Anruf auf der Leitung 17 clobbers die Eingabedatei nach einem Block von ihm gelesen wurde.
Ich kann das natürlich umgehen, indem ich in eine temporäre Datei schreibe und sie am Ende umbenenne.Aber ich bin ein wenig enttäuscht, nach ein paar Stunden Debugging, dass das Beispiel in Perlrun nicht so ist Allzweck, wie ich es erwartet hatte
Gibt es einen Standard, idiomat ic Weg, um mit dem
$extension eq ''
Fall umzugehen?Ist dieser
$extension eq ''
Anwendungsfall wichtig genug, dass perlrun bearbeitet werden sollte? Natürlich bedeutet die Klausel "und Ihr System unterstützt es", dass das Beispiel nicht falsch ist, aber das Beispiel wäre nützlicher, wenn es auch diesen Fall abdeckt.
Der Grund für die Beispiel-Programm korrekt ist, ist, dass das Beispielprogramm über '-i ist. orig', nicht über '-i' ohne Erweiterung. Ich weiß nicht, warum Sie erwarten, dass sich das Beispielprogramm wie "-i" verhält, wenn Sie lediglich die '.orig' im Programm löschen. (Das ist so, als ob man '5 * 5 == 25 'sieht und davon ausgeht, dass' 8 * 8 == 28 'ist.) Seine Korrektheit hat nichts mit der Klausel" und Ihr System unterstützt es "zu tun, ob Ihr System dies unterstützt Halten Sie einen offenen Handle zu einer nicht verknüpften Datei. – ruakh
(Übrigens ist es nicht '-i ''', sondern einfach nur '-i' ohne Argument. Und String-Vergleich benutzt' eq', nicht '=='.) – ruakh
Obwohl Sie es '-i schreiben könnten "". – ikegami