2012-01-30 12 views

Respuesta

6

De los print manpage: mangos

Si se almacenan en una matriz o hachís, o en general siempre está utilizando cualquier expresión más compleja que un mango o una bareword llanura, escalares unsubscripted variable para recuperarlo, tendrá que usar un bloque devolviendo el valor del identificador de archivo en su lugar.

Debería utilizar:

print { $$self{tmp_db_fh} } "Bob\n"; 

Este código no funcionará bajo use strict. Para solucionarlo sólo tiene que utilizar una variable my:

open my $fh, ">", "data.txt" or die $!; 
$$self{tmp_db_fh} = $fh; 
print { $$self{tmp_db_fh} } "Bob\n"; 
+1

Esto no funcionará con 'utilizar estrictas 'referencias';' – dgw

+0

hice buscar muchos lugares, pero nunca tuve esa página. Muchas gracias. –

0

Filehandles solo pueden ser escalares.

Pero $$self{tmp_db_fh} es o bien un gestor de archivo abierto (a datos.txt) entonces esto funcionaría:

sub _init_tmp_db 
{ 
    my ($self) = @_; 

    my $filehandle = $$self{tmp_db_fh} ; 
    print $filehandle "Bob\n"; 
} 

o se abre el gestor de archivo dentro _init_tmp_db

sub _init_tmp_db 
{ 
    my ($self) = @_; 

    open my $filehandle , ">", "data.txt" or die "Cannot open data.txt" ; 
    print $filehandle "Bob\n"; 
} 

Pero proporcionar una cadena en $$self{tmp_db_fh} (como 'ARCHIVO DE ARCHIVO') no funcionará.

4

Usted debe el módulo de IO :: File lugar.

use IO::File; 
my $file = IO::File->new; 
$file->open("> data.txt"); 

print_something($file); 

sub print_something { 
    my ($file) = @_; 
    $file->print("hello world\n"); 
} 

O en su función de ejemplo:

use IO::File; 
# ... 
sub _init_tmp_db 
{ 
    my ($self) = @_; 

    $self{tmp_db_fh} = IO::File->new; 
    $self{tmp_db_fh}->open(">", "data.txt"); 
    $self{tmp_db_fh}->print"Bob\n"; 
} 

(nota, puede todavía no -> basada llamadas también, pero me escribió lo anterior utilizando la más tradicional -> open() el tipo de llamadas .)

+0

Thx por sugerencia pero, en este momento, todos los demás archivos que abro en mi método de uso del código actual como en la pregunta. –

+0

Está bien, el módulo IO :: File también funcionará de esa manera. IE, es seguro hacer 'open ($ self {tmp_db_fh},"> "," data.txt ")' y funcionará muy bien, una vez que haya creado el manejador IO :: File. –

+0

No ** necesita ** para usar [IO :: File] (http://perldoc.perl.org/IO/File.html). Como es habitual con Perl [TMTOWTDI] (http://en.wikipedia.org/wiki/TMTOWTDI). –

0

Esto se resuelve fácilmente mediante la creación de una variable para un identificador de archivo:

sub _init_tmp_db { 
    my $self = shift; 

    my $fh; 
    open $fh, ">", "data.txt" 
    $self->{temp_db_fh} = $fh; 

    # Sometime later... 

    $fh = $self-{temp_db_hf}; 
    print $fh "Bob\n"; 
} 

Este es un problema porque la forma en que se procesa la sintaxis print y el descuido temprano de la sintaxis. La declaración print tiene realmente dos formatos separados: el formato n. ° 1 es que simplemente lo está pasando para imprimir. El formato n. ° 2 dice que el primer elemento puede ser un identificador de archivo y el resto es lo que desea imprimir en el manejador de archivo. Si print no puede determinar fácilmente que el primer parámetro es un identificador de archivo, falla.

Si observa otros idiomas, usarán un parámetro para pasar el identificador del archivo y tal vez las cosas para imprimir. O en los lenguajes orientados a objetos, van a sobrecargar >> para el parámetro del identificador de archivo. Se van a ver algo como esto:

print "This is my statement", file=file_handle; 

o

print "This is my statement" >> file_handle; 

Usted podría ser capaz de munge la sintaxis para alejarse del uso de una variable. Sin embargo, no hace que el programa sea más eficiente o más legible, y puede hacer que el programa sea más difícil de mantener. Entonces, solo usa una variable para el manejador de archivo.


Dijiste clase en su título. Supongo que está interesado en escribir un paquete orientado a objetos totalmente dedicado para hacer esto. Aquí hay un ejemplo rápido. Aviso en el write subrutina método Recupero el identificador de archivo en una variable y uso la variable en la instrucción print.

#! /usr/bin/env perl 
# 
use strict; 
use warnings; 


####################################################### 
# MAIN PROGRAM 
# 
my $file = File->new; 

$file->open("OUTPUT") or 
    die "Can't open 'OUTPUT' for writing\n"; 

$file->write("This is a test"); 
# 
####################################################### 

package File; 
use Carp; 


sub new { 
    my $class = shift; 

    my $self = {}; 
    bless $self, $class; 

    return $self; 
} 

sub open { 
    my $self = shift; 
    my $file = shift; 

    my $fh; 
    if (defined $file) { 
     $self->{FILE} = $file; 
     open ($fh, ">", $file) and $self->_fh($fh); 
    } 
    return $self->_fh; 
} 

sub _fh { 
    my $self = shift; 
    my $fh = shift; 

    if (defined $fh) { 
     $self->{FH} = $fh; 
    } 
    return $self->{FH}; 
} 

sub write { 
    my $self = shift; 
    my $note = shift; 

    my $fh = $self->_fh; 
    print $fh $note . "\n"; 
    return 
} 
Cuestiones relacionadas