在Perl 5.6之后,Symbol::gensym还有用吗?

6
我看到了这样的代码:

my $fh = gensym;                                             
open $fh, ">$name" or die "Can't create $name: $!";

这可以写成:

open my $fh, ">$name" or die "Can't create $name: $!";

gensym只是传统还是在某些场合仍然有用?

1个回答

8

传统的技术。有些较老的模块需要使用通配符而非词法变量,但只限于此。

use IPC::Open3 qw( open3 );
open(local *CHILD_STDIN, '<', '/dev/null') or die $!;
my $pid = open3(
   '<&CHILD_STDIN',
   my $CHILD_STDOUT = gensym(),
   my $CHILD_STDERR = gensym(),
   $cmd, @args,
);

仔细想想,您还可以使用它们创建别名(虽然Data::Alias可以通过词法来实现这一点)。

my $foo;
our $bar; local *bar = \$foo;
$foo = 123; say $bar;  # 123
$bar = 456; say $foo;  # 456

你的意思是如果我直接传递 my $CHILD_STDOUT,它就不能正常工作吗? - new_perl
@new_perl,对于stdout,这将起作用,但不适用于stderr。但也请注意,stdin使用了glob。(谈论“gensym”很愚蠢,因为它只是\local *NAME,但每次都有一个新名称。) - ikegami
1
如果你在第一个和/或第二个参数中传递了undefopen3将为你调用gensym。(这意味着我的$CHILD_STDOUT实际上是my $CHILD_STDOUT = gensym())如果你在第三个参数中传递了undefopen3将使用与第二个参数相同的句柄。换句话说,第三个参数的undef就像shell的2>&1 - ikegami
为什么open3必须将glob的引用作为参数,而不是简单标量的引用? - new_perl
为什么需要一个标量的引用? - ikegami
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接