如何在Perl子例程中使用$ a和$ b
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Perl子例程中使用$ a和$ b相关的知识,希望对你有一定的参考价值。
我想在我的匿名二进制函数中使用$a
和$b
变量,就像它在sort {$a <=> $b} (1, 2, 3)
中完成但我无法弄清楚为什么代码像
#!/usr/bin/env perl
use strict;
use warnings;
Foo::Bar(sub { $a + $b });
package Foo;
sub Bar {
my ($function) = @_;
for my $i (1, 2, 3) {
local ($a, $b) = ($i, $i);
print $function->() . "
";
}
}
不起作用。而
#!/usr/bin/env perl
use strict;
use warnings;
Foo::Bar(sub { $_ });
package Foo;
sub Bar {
my ($function) = @_;
for my $i (1, 2, 3) {
local $_ = $i;
print $function->() . "
";
}
}
工作良好。
我究竟做错了什么?
答案
$a
和$b
是特殊的包变量。你在Foo::Bar
包中调用main
,所以你需要设置$main::a
和$main::b
才能使它工作。您可以使用caller
获取调用包的名称。这应该工作:
#!/usr/bin/env perl
use strict;
use warnings;
Foo::Bar(sub { $a + $b });
package Foo;
sub Bar {
my ($function) = @_;
my $pkg = caller;
for my $i (1, 2, 3) {
no strict 'refs';
local *{ $pkg . '::a' } = $i;
local *{ $pkg . '::b' } = $i;
print $function->() . "
";
}
}
另一答案
如果有人有兴趣,可以从List::MoreUtils::PP v.0.428(截至2017年12月)复制粘贴:
# begin copyrighted content
sub reduce_u(&@)
{
my $code = shift;
# Localise $a, $b
my ($caller_a, $caller_b) = do
{
my $pkg = caller();
no strict 'refs';
*{$pkg . '::a'}, *{$pkg . '::b'};
};
local (*$caller_a, *$caller_b);
*$caller_a = ();
for (0 .. $#_)
{
*$caller_b = $_[$_];
*$caller_a = ($code->());
}
${*$caller_a};
}
# end copyrighted content
它仅与受上述no strict 'refs';
影响的区域中的上述样本不同。如果没有严格要求,可能无法完成。
以上是关于如何在Perl子例程中使用$ a和$ b的主要内容,如果未能解决你的问题,请参考以下文章