2009-02-12 12 views
8

que tienen una línea de código a lo largo de las líneas de:

print $somehash{$var}{fh} "foo"; 

El hash contiene el gestor de archivo de unos niveles más abajo. El error es:

String found where operator expected at test.pl line 10, near "} "foo"" 

puedo solucionarlo haciendo esto:

my $fh = $somehash{$var}{fh}; 
print $fh "foo"; 

... pero hay una sola línea?

+0

Puedes "decir" lo que quieras. Lo está poniendo a trabajar que es complicado :) –

Respuesta

23

ver http://perldoc.perl.org/functions/print.html

Tenga en cuenta que si usted está almacenando filehandles en una matriz, o si está usando cualquier otra expresión más compleja de lo que una variable escalar a recuperarlo, se tendrá que utilizar un bloque devolver el valor gestor de archivo lugar: ...

Así, en su cas e, se utiliza un bloque de la siguiente manera:

print { $somehash{$var}{fh} } "foo"; 
+2

Excelente respuesta, y solo para hacerlo concreto: print {$ somehash {$ var} {fh}} "foo"; – andy

+0

Buen punto @andy, edité la respuesta para incluir esa línea de código. Las ediciones son bienvenidas aquí, pruébalo la próxima vez. – Flimm

10

Si tiene que no sea un escalar simple como su gestor de archivo nada, es necesario envolver la retención de referencia del gestor de archivo en apoyos de modo Perl sabe cómo analizar la declaración:

print { $somehash{$var}{fh} } $foo; 

Parte de Perl Best Practices indica que siempre envolver filehandles en los apoyos sólo por esta razón, a pesar de que no entiendo que a nuez con él.

La sintaxis es extraño porque print es un método indirecto en un objeto gestor de archivo:

method_name Object @arguments; 

Es posible que haya visto esto en la vieja escuela CGI.pm. Aquí hay dos llamadas a métodos indirectos:

use CGI; 

my $cgi_object = new CGI 'cat=Buster&bird=nightengale'; 

my $value = param $cgi_object 'bird'; 

print "Indirect value is $value\n"; 

que casi funciona bien (véase Schwern's answer about the ambiguity), siempre y cuando el objeto está en un simple escalar. Sin embargo, si puse el $cgi_object en un hash, obtengo el mismo error de sintaxis que obtuve con print. Puedo poner llaves en el acceso hash para que funcione. Continuando con el código anterior:

my %hash; 

$hash{animals}{cgi} = $cgi_object; 

# $value = param $hash{animals}{cgi} 'cat'; # syntax error 
$value = param { $hash{animals}{cgi} } 'cat'; 
print "Braced value is $value\n"; 

Eso es todo un poco torpe por lo que sólo tiene que utilizar la notación de flecha para todo, en su lugar:

my $cgi_object = CGI->new(...); 
$cgi_object->param(...); 

$hash{animals}{cgi}->param(...); 

Usted puede hacer lo mismo con los controladores de archivo, aunque hay que utilizar el IO::Handle módulo para hacer que todo funcione:

use IO::Handle; 

STDOUT->print('Hello World'); 

open my($fh), ">", $filename or die ...; 
$fh->print(...); 

$hash{animals}{fh} = $fh; 

$hash{animals}{fh}->print(...); 
5

Las respuestas anteriores son todas correctas. La razón por la que no permiten una expresión completa allí es print FH LIST ya es una sintaxis bastante extraña. Poner algo más complicado allí introduciría una tonelada de sintaxis ambigua. El bloque eliminó esa ambigüedad.

Para ver a dónde lleva esta locura, considere el horror que es la sintaxis indirecta del objeto.

foo $bar; # Is that foo($bar) or $bar->foo()? Good luck! 
Cuestiones relacionadas