Esto es más una sugerencia sobre cómo NO hacerlo. Lo he pasado mal para encontrar un error en una aplicación Perl bastante grande. La mayoría de los módulos tenían sus propios archivos de configuración. Para leer los archivos de configuración en su conjunto, encontré esta única línea de Perl en algún lugar de Internet:
# Bad! Don't do that!
my $content = do{local(@ARGV,$/)=$filename;<>};
Reasigna el separador de línea como se explicó anteriormente. Pero también reasigna el STDIN.
Esto tuvo al menos un efecto secundario que me costó horas encontrarlo: no cierra correctamente el identificador de archivo implícito (ya que no llama close
en absoluto).
Por ejemplo, haciendo eso:
use strict;
use warnings;
my $filename = 'some-file.txt';
my $content = do{local(@ARGV,$/)=$filename;<>};
my $content2 = do{local(@ARGV,$/)=$filename;<>};
my $content3 = do{local(@ARGV,$/)=$filename;<>};
print "After reading a file 3 times redirecting to STDIN: $.\n";
open (FILE, "<", $filename) or die $!;
print "After opening a file using dedicated file handle: $.\n";
while (<FILE>) {
print "read line: $.\n";
}
print "before close: $.\n";
close FILE;
print "after close: $.\n";
resulta en:
After reading a file 3 times redirecting to STDIN: 3
After opening a file using dedicated file handle: 3
read line: 1
read line: 2
(...)
read line: 46
before close: 46
after close: 0
Lo extraño es que el contador de líneas $.
aumenta en uno para cada archivo. No se restablece y no contiene el número de líneas. Y no se restablece a cero al abrir otro archivo hasta que se lee al menos una línea. En mi caso, estaba haciendo algo como esto:
while($. < $skipLines) {<FILE>};
Debido a este problema, la condición era falsa porque el contador de línea no se restableció correctamente. No sé si esto es un error o simplemente un código incorrecto ... Además, llamar a close;
oder close STDIN;
no ayuda.
Reemplacé este código ilegible usando abrir, concatenación de cadenas y cerrar. Sin embargo, la solución publicada por Brad Gilbert también funciona, ya que utiliza un identificador de archivo explícito.
Las tres líneas al principio se pueden reemplazar por:
my $content = do{local $/; open(my $f1, '<', $filename) or die $!; my $tmp1 = <$f1>; close $f1 or die $!; $tmp1};
my $content2 = do{local $/; open(my $f2, '<', $filename) or die $!; my $tmp2 = <$f2>; close $f2 or die $!; $tmp2};
my $content3 = do{local $/; open(my $f3, '<', $filename) or die $!; my $tmp3 = <$f3>; close $f3 or die $!; $tmp3};
que cierra correctamente el identificador del archivo.