Nella descrizione della funzione Perl -i[extension]
a http://perldoc.perl.org/perlrun.html, codice che è sostanzialmente identico al seguente programma è data come "equivalente" per usando perl -pi.orig ...
:Come è implementato perl -i * realmente *?
#!/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);
Questo funziona bene quando $extension eq '.orig'
; tuttavia, Perl definisce -i
senza alcuna estensione (ovvero, per $extension eq ''
). comportamento definito di Perl è quello di modificare il file in luogo, senza file di backup creato:
Se nessuna estensione è fornito, e il vostro sistema supporta, il file originale viene mantenuto aperto senza un nome, mentre l'output viene reindirizzato a un nuovo file con il nome file originale. Quando perl esce, pulito o no, il file originale è scollegato.
Forse il mio sistema (Mac OS X Yosemite 10.10.3) non lo supporta.
Se ho impostato $extension = ''
in questo programma, quindi il codice funziona bene per i file più piccolo di un blocco di STDIN (4096 byte in AcivePerl 5.10, ma 8192 byte di ActivePerl 5.16), ma sarà non lavoro per i file più grande di un blocco.
Sembra a me che, sul mio sistema, se $ARGV
e $backup
hanno lo stesso valore (cui si intende se $extension eq ''
, poi la chiamata open(ARGVOUT, ">$ARGV")
on line 17 clobbers il file di input dopo un isolato di esso è stato letto.
Posso ovviare a questo, ovviamente, scrivendo su un file temporaneo e poi rinominandolo alla fine, ma sono un po 'deluso, dopo un paio di ore di debug, che l'esempio in perlrun non è così come mi ero aspettato.
C'è un idioma standard modo migliore per gestire il caso
$extension eq ''
?È questo il caso d'uso
$extension eq ''
abbastanza importante che perlrun deve essere modificato? Naturalmente, la clausola "e il tuo sistema lo supporta" significa che l'esempio non è errato, ma l'esempio sarebbe più utile se riguardasse anche questo caso.
Il motivo per il programma di esempio è corretta è che il programma di esempio è di circa '-i. orig', non su '-i' senza estensione. Non so perché ti aspetti che il programma di esempio si comporti come '-i' se cancelli semplicemente' .orig' all'interno del programma. (È come vedere '5 * 5 == 25' e assumendo che quindi' 8 * 8 == 28'.) La sua correttezza non ha nulla a che fare con la clausola "e il tuo sistema lo supporta", che riguarda se il tuo sistema supporta mantenendo un handle aperto per un file non collegato. – ruakh
(A proposito, non è '-i ''', ma si trova semplicemente '-i' senza argomenti e il confronto tra stringhe usa' eq', non '=='.) – ruakh
Anche se si potrebbe scrivere '-i '' '. – ikegami