Perl: Как передать и использовать лексический дескриптор файла в подпрограмме в качестве именованного аргумента? - PullRequest
7 голосов
/ 25 июня 2010

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

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

РаботаетХорошо, когда я использую примитивную технику передачи аргументов, а техника хэширования именованных аргументов работает для части message , но не для части дескриптора файла .Нужна ли мне новая версия print ?

Ответы [ 2 ]

17 голосов
/ 25 июня 2010

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

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

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

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

my $fh = $args->{fh};
print $fh $args->{m};
4 голосов
/ 25 июня 2010

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

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

sophisticated(fh => $log_fh, m => "Hello, world!\n");
...