2011-02-08 18 views
6

Estoy tratando de abrir el archivo recibido como argumento.Perl: Archivo de apertura

Cuando almaceno el argumento de que la variable global abierta funciona correctamente.

Pero

Si utilizo dar que sea lo más abierto mi no abierta el archivo.

¿Cuál es el motivo?

#use strict; 
use warnings; 

#my $FILE=$ARGV[0]; #open Fails to open the file $FILE 

$FILE=$ARGV[0];  #Works Fine with Global $FILE 
open(FILE) 
    or 
die "\n ". "Cannot Open the file specified :ERROR: $!". "\n"; 
+6

Este estilo de Perl es ** manera ** obsoleto. Sería mucho mejor que abriera mi archivo $, "<", $ ARGV [0] ... o mejor aún, no llame en absoluto y simplemente lea desde ARGV.(Perl asume que los argumentos son archivos que se deben abrir para la entrada, y los abre automágicamente). –

+1

Se ha documentado que la apertura unaria solo funciona en las variables del paquete. – tchrist

+0

@William: ¿No debería haber una codificación allí? 'open (FH," <: encoding (UTF-8) ", $ pathname)' – tchrist

Respuesta

13

Unary abierto solo funciona en variables de paquete (globales). Esto está documentado en the manpage.

Una mejor manera de abrir un archivo para lectura sería:

my $filename = $ARGV[0];   # store the 1st argument into the variable 
open my $fh, '<', $filename or die $!; # open the file using lexically scoped filehandle 

print <$fh>; # print file contents 

P. S. siempre use strict y warnings mientras depura sus scripts de Perl.

+2

Esta respuesta pierde el sentido. La simple pregunta era por qué abrir unario solo funciona con variables de paquete. La respuesta simple es que es porque está documentado. Todo lo demás es glaseado en un pastel que falta. – tchrist

+0

@tchrist: ok, agregué esto a la respuesta –

+0

Gracias. Normalmente, no rechazo respuestas que hayan sido una buena oportunidad (por eso no lo hice aquí). Prefiero señalar lo que se perdieron. Gracias por arreglarlo. – tchrist

7

Todo está en perldoc -f open:

Si se omite EXPR, la variable escalar del mismo nombre que el FILEHANDLE contiene el nombre del archivo. (Tenga en cuenta que las variables léxicas - las declaradas con "mi" - no va a funcionar para este propósito ; así que si usted está utilizando "mi", especifique EXPR en su llamada a abrir.)

Tenga en cuenta que esta no es una muy buena manera de especificar el nombre del archivo. Como puede ver, tiene una restricción estricta en el tipo de variable en el que se encuentra y, por lo general, es mejor evitar la variable global que requiere o el identificador de archivo global que abre.

El uso de un gestor de archivo léxica mantiene su alcance de control, y las manijas de cierre automático:

open my $fh, '<', "filename" or die "string involving $!"; 

Y si usted está tomando ese nombre de archivo desde la línea de comandos, lo que pueda arrancar ese open o cualquier manejar por completo, y usar el operador simple <> para leer desde argumentos de línea de comandos o STDIN. (Consulte los comentarios para obtener más información al respecto)

+0

Buen punto: por lo general es Es mucho mejor usar magia ARGV que una apertura explícita. Pero agrega 'if (! @ARGV && -t STDIN) {warn" $ 0: leyendo de stdin ... \ n "}' para ayudar a las personas cuyos sistemas carecen de un '^ T' tty char apropiado. Sin embargo, el ARGV mágico solo usa stdin cuando '@ ARGV' está inicialmente vacío, no cuando está agotado; tu respuesta sugiere lo contrario. – tchrist

+0

@tchrist: sí y no ... después de '<>' agotado ARGV y devuelto undef una vez (lo que estabas diciendo), comenzará de nuevo, con un @ARGV vacío si no has hecho nada al respecto, por lo tanto recurrir a STDIN (lo que estaba diciendo). Reconozco que la mayoría de las personas no pasarán los primeros undef espontáneamente y editarán. –

+0

Um, I ** do ** sé cómo '<>' funciona. :) – tchrist

6
use strict; 
use warnings; 

my $file_name = shift @ARGV; 
open(my $file, '<', $file_name) or die $!; 
… 
close($file); 

Siempre use strict y warnings. Si alguno de ellos se queja, arregle el código, no comente los pragmas. También puede use autodie para evitar el or die explícito después de abrir, consulte autodie.

+1

+1 y hay que decirlo de nuevo: si 'strict' se queja, significa que necesitas arreglar tu código, no que necesites comentar' strict'. –

+0

Lo he dicho antes, lo diré de nuevo: * Esta respuesta no entiende el punto. La simple pregunta era por qué abrir unario solo funciona con variables de paquete. La respuesta simple es que es porque está documentado. Todo lo demás es glaseado en una torta que falta. * Además, olvidaste especificar la codificación como en 'abrir (FH," <: codificación (UTF-8) ", $ ruta)'. Y si uno es tan cuidadoso, ¿no debería uno probar '' ARGV' por razones? Finalmente, ¿cómo pueden saber que ** NO ** quieren permitir nombres de archivos como '-' en la forma estándar de Unix de especificar std {in, out, whatever}? – tchrist

+1

Además, esta es una expresión realmente mala. Perl ya maneja automáticamente la apertura de archivos enumerados como argumentos a través de ARGV. En Perl, casi nunca hay una buena razón para abrir explícitamente un archivo cuyo nombre se da en @ARGV –

3

De Perl's docs for open()

Si se omite EXPR, la variable escalar del mismo nombre que el FILEHANDLE contiene el nombre del archivo. (Tenga en cuenta que las variables léxicas - aquellas declaradas con mi - no funcionarán para este propósito, así que si está usando mi, especifique EXPR en su llamada para abrir.)

+0

sucinto, correcto y al grano. – tchrist

Cuestiones relacionadas