Perl: Как передать и использовать лексический дескриптор файла для подпрограммы как параметр, передаваемый по имени?

Я хочу передать лексический дескриптор файла подпрограмме с помощью параметра, передаваемого по имени, но следующее не компилирует:

#!/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

Это работает хорошо. когда я использую примитивный метод передающих аргументов и работы метода хеша параметра, передаваемого по имени для части сообщения, просто не для части дескриптора файла. Мне нужна новая версия печати?

7
задан Thomas L Holaday 28 June 2010 в 13:56
поделиться

2 ответа

Когда у вас есть сложное выражение, которое возвращает дескриптор файла (например, $ args -> {fh} ), вам нужно немного устранить неоднозначность синтаксиса, добавив некоторые дополнительные фигурные скобки:

print { $args->{fh} } $args->{m};

Это связано со странным способом разработки оператора print , без запятой между дескриптором файла и списком материалов для печати.

В качестве альтернативы вы можете сначала получить дескриптор файла из hashref аргументов, например

my $fh = $args->{fh};
print $fh $args->{m};
17
ответ дан 6 December 2019 в 08:41
поделиться

ответ friedo касается вашей проблемы, но есть стилистическая проблема, на которую я хотел бы указать. Вам не нужно оборачивать все анонимным хешем для имитации именованных аргументов. Инициализатор хэша - это просто список, интерпретируемый как пары ключ / значение. Передача такого списка в подпрограмму обеспечивает более чистый синтаксис для вызывающего:

sub sophisticated {
   my %arg = @_;
   print $arg{m};
   print {$arg{fh}} $arg{m};
}

sophisticated(fh => $log_fh, m => "Hello, world!\n");
4
ответ дан 6 December 2019 в 08:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: