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哈希有一个主要优点。如果意外传递奇数个值,则警告将出现在调用代码中,而不是被调用函数中。