Я хочу передать лексический дескриптор файла подпрограмме с помощью параметра, передаваемого по имени, но следующее не компилирует:
#!/usr/bin/perl -w
use strict;
my $log_fh;
my $logname = "my.log";
sub primitive {
my ($fh, $m) = @_;
print $fh $m;
}
sub sophisticated {
my ($args) = @_;
print $args->{m};
print $args->{fh} $args->{m} ;
}
open $log_fh, ">", $logname;
print $log_fh "Today I learned ...\n";
primitive($log_fh,"... the old way works ...\n");
sophisticated({
fh=>$log_fh,
m=>"... and the new way requires an intervention by SO.",
});
close $log_fh;
Жалоба:
Scalar found where operator expected at ./lexical.file.handle.pl line 15, near
} $args"
(Missing operator before $args?)
$ perl --version
This is perl, v5.10.1
Это работает хорошо. когда я использую примитивный метод передающих аргументов и работы метода хеша параметра, передаваемого по имени для части сообщения, просто не для части дескриптора файла. Мне нужна новая версия печати?
Когда у вас есть сложное выражение, которое возвращает дескриптор файла (например, $ args -> {fh}
), вам нужно немного устранить неоднозначность синтаксиса, добавив некоторые дополнительные фигурные скобки:
print { $args->{fh} } $args->{m};
Это связано со странным способом разработки оператора print
, без запятой между дескриптором файла и списком материалов для печати.
В качестве альтернативы вы можете сначала получить дескриптор файла из hashref аргументов, например
my $fh = $args->{fh};
print $fh $args->{m};
ответ friedo касается вашей проблемы, но есть стилистическая проблема, на которую я хотел бы указать. Вам не нужно оборачивать все анонимным хешем для имитации именованных аргументов. Инициализатор хэша - это просто список, интерпретируемый как пары ключ / значение. Передача такого списка в подпрограмму обеспечивает более чистый синтаксис для вызывающего:
sub sophisticated {
my %arg = @_;
print $arg{m};
print {$arg{fh}} $arg{m};
}
sophisticated(fh => $log_fh, m => "Hello, world!\n");