Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl:如何将词法文件句柄作为命名参数传递和使用到子例程?_Perl_Subroutine - Fatal编程技术网

Perl:如何将词法文件句柄作为命名参数传递和使用到子例程?

Perl:如何将词法文件句柄作为命名参数传递和使用到子例程?,perl,subroutine,Perl,Subroutine,我想使用命名参数将词法文件句柄传递给子例程,但无法编译以下内容: #!/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} $a

我想使用命名参数将词法文件句柄传递给子例程,但无法编译以下内容:

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

当我使用传递参数的原语技术,命名参数散列技术适用于消息部分,而不适用于文件句柄部分时,它工作正常。我需要新版本的print吗?

当您有一个返回文件句柄的复杂表达式时(如
$args->{fh}
),您需要通过添加一些额外的卷曲来消除语法的歧义:

print { $args->{fh} } $args->{m};
这是因为
print
操作符的设计方式很奇怪,文件句柄和要打印的内容列表之间没有逗号

或者,您可以先从参数hashref中获取文件句柄,例如

my $fh = $args->{fh};
print $fh $args->{m};
涵盖了你的问题,但我想指出一个风格问题。您不需要将所有内容都封装在匿名散列中以模拟命名参数。哈希初始值设定项只是一个解释为键/值对的列表。将此类列表传递给sub可为调用者提供更清晰的语法:

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

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

另请参见:您应该改掉预先声明变量的习惯(“my$log\u fh;”是不必要的),并且应该检查打开的状态。例如:打开我的$log\U fh,“>”,$logname或die“打开$logname:$!”时出错;这是因为您正在对
print
使用间接对象语法。奇怪的是,如果您执行
$args{fh}->打印('blah')使用IO::Handle否则会出现错误。但是使用间接表示法就没有必要了。有关更多信息,请参阅。这应该是一个注释,而不是答案。对命名参数使用anon哈希有一个主要优点。如果意外传递奇数个值,则警告将出现在调用代码中,而不是被调用函数中。