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

发布于 2024-09-07 19:11:55 字数 848 浏览 7 评论 0原文

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

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

I want to pass a lexical file handle to a subroutine using a named argument, but the following does not compile:

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

The complaint is:

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

It works O.K. when I use the primitive technique of passing arguments, and the named-argument hash technique works for the message portion, just not for the file handle portion. Do I need a new version of print ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你的他你的她 2024-09-14 19:11:55

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

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

这是由于print 运算符的设计方式很奇怪,文件句柄和要打印的内容列表之间没有逗号。

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

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

When you've got a complex expression that returns a filehandle (like $args->{fh}) you'll need to disambiguate the syntax a bit by adding some extra curlies:

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

This is due to the weird way the print operator is designed, with no comma between the filehandle and the list of stuff to print.

Alternatively, you could grab the filehandle out of your arguments hashref first, e.g.

my $fh = $args->{fh};
print $fh $args->{m};
谜兔 2024-09-14 19:11:55

friedo的答案涵盖了您的问题,但我想指出一个风格问题。您不需要将所有内容包装在匿名哈希中来模拟命名参数。哈希初始值设定项只是一个解释为键/值对的列表。将这样的列表传递给子进程为调用者提供了更清晰的语法:

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

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

friedo's answer covers your problem, but there's a stylistic issue I'd like to point out. You don't need to wrap everything in an anonymous hash to emulate named arguments. A hash initializer is just a list interpreted as key/value pairs. Passing such a list to a sub provides a cleaner syntax for the caller:

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

sophisticated(fh => $log_fh, m => "Hello, world!\n");
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文