我想使用命名参数将词法文件句柄传递给子例程,但以下内容不能编译:
#!/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
它适用于O.K.当我使用传递参数的原始技术时,命名参数哈希技术适用于消息部分,而不适用于文件句柄部分。我是否需要 print 的新版本?
答案 0 :(得分:17)
如果你有一个返回文件句柄的复杂表达式(比如$args->{fh}
),你需要通过添加一些额外的curlies来消除语法歧义:
print { $args->{fh} } $args->{m};
这是由于设计print
运算符的奇怪方式,文件句柄和要打印的东西列表之间没有逗号。
或者,您可以先从参数hashref中获取文件句柄,例如
my $fh = $args->{fh};
print $fh $args->{m};
答案 1 :(得分:4)
friedo's answer涵盖了您的问题,但有一个风格问题我想指出。您不需要将所有内容都包装在匿名哈希中以模拟命名参数。哈希初始值设定项只是一个被解释为键/值对的列表。将这样的列表传递给sub为调用者提供了更清晰的语法:
sub sophisticated {
my %arg = @_;
print $arg{m};
print {$arg{fh}} $arg{m};
}
sophisticated(fh => $log_fh, m => "Hello, world!\n");