如何在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的主要内容,如果未能解决你的问题,请参考以下文章

仅在子例程中需要时才使用 Perl 模块

将两个或多个数组传递给 Perl 子例程

在子例程中保留 VBA 函数值

如何让 VBA 子例程调用将数组传递给子例程中的另一个函数的函数

什么时候应该使用 & 来调用 Perl 子例程?

模块化程序-子例程