Если у вас есть что-то кроме простого скаляра в качестве дескриптора файла, вам нужно обернуть ссылку, содержащую дескриптор файла, в фигурные скобки, чтобы Perl знал, как проанализировать оператор:
print { $somehash{$var}{fh} } $foo;
Часть Perl Best Practices говорит, что всегда оборачивайте файловые дескрипторы в фигурные скобки именно по этой причине, хотя я не слишком разбираюсь в этом.
Синтаксис странный, потому что print
является косвенным методом для объекта дескриптора файла:
method_name Object @arguments;
Возможно, вы видели это в старой школе CGI.pm . Вот два косвенных вызова метода:
use CGI;
my $cgi_object = new CGI 'cat=Buster&bird=nightengale';
my $value = param $cgi_object 'bird';
print "Indirect value is $value\n";
Это почти нормально работает (см. ответ Шверна о неоднозначности ), если объект находится в простом скаляре. Однако, если я добавлю $cgi_object
в хеш, я получу ту же синтаксическую ошибку, что и с print
. Я могу поставить скобки вокруг доступа к хешу, чтобы все получилось. Продолжая с предыдущим кодом:
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";
Это все немного неуклюже, поэтому просто используйте обозначение стрелки для всего:
my $cgi_object = CGI->new( ... );
$cgi_object->param( ... );
$hash{animals}{cgi}->param( ... );
Вы можете сделать то же самое с файловыми дескрипторами, хотя вы должны использовать модуль IO :: Handle , чтобы все это работало:
use IO::Handle;
STDOUT->print( 'Hello World' );
open my( $fh ), ">", $filename or die ...;
$fh->print( ... );
$hash{animals}{fh} = $fh;
$hash{animals}{fh}->print( ... );