Perl sub里面有一个sub

PMa*_*Mat 3 perl

我想在另一个子里面有一个子,

sub a {
    sub b {
    }
}
Run Code Online (Sandbox Code Playgroud)

我想sub b为每次调用创建一个新实例sub a.有没有办法在Perl中执行此操作?

当我运行上面的代码,并打印的地址sub bsub a我总是得到相同的地址sub b一样

sub a {
    print \&b;
    sub b{
    }
}
Run Code Online (Sandbox Code Playgroud)

Perl Monks上的这个链接说我们可以做到这一点,但我总是看到相同的地址sub b.

有没有办法sub b为每次调用创建一个新实例sub a

sno*_*kin 10

sub a {
    sub b{
    }
}
Run Code Online (Sandbox Code Playgroud)

基本相同:

sub a {

}
sub b{
}
Run Code Online (Sandbox Code Playgroud)

因为命名子程序存在于符号表中,因此它们是全局的.您将需要返回对子例程的引用.


adr*_*anh 7

命名子程序仅创建一次.您需要返回一个匿名子例程引用,如下所示:

sub a {
    my $counter = 1;
    return sub {
        return $counter++;
    }
}

my $c1 = a();
my $c2 = a();

# different references
print "c1 = $c1, c2 = $c2\n";

# each has a different counter
print "c1 ", $c1->(), "\n";
print "c1 ", $c1->(), "\n";
print "c2 ", $c2->(), "\n";
print "c2 ", $c2->(), "\n";
Run Code Online (Sandbox Code Playgroud)


Jon*_*ler 5

您可以创建对匿名子的引用:

#!/usr/bin/env perl
use strict;
use warnings;

sub a
{
    my($b) = @_;
    my $subref = sub { my($a) = @_; print "a = $a; b = $b\n"; return $a + $b; };
    &$subref(3);
    return $subref;
}

my $sub1 = a(10);
my $a10  = &$sub1(19);
my $sub2 = a(20);
my $a20  = &$sub2(20);
print "a10 = $a10; a20 = $a20; sub1 = $sub1; sub2 = $sub2\n";
Run Code Online (Sandbox Code Playgroud)

样本输出:

a = 3; b = 10
a = 19; b = 10
a = 3; b = 20
a = 20; b = 20
a10 = 29; a20 = 40; sub1 = CODE(0x7ffc3c002eb8); sub2 = CODE(0x7ffc3c032eb8)
Run Code Online (Sandbox Code Playgroud)

  • @Borodin:是的,关于`$a` 和`$b` 确实如此,但OP 使用了它,所以为了保持它对问题的引用,我认为这里是可以接受的。而且我认为我从未听说过使用 `&` 是错误的。程序员应该只知道`&foo` 与`&foo()` 或`foo()` 不同,但我认为他在上面正确使用了它。 (3认同)
  • @Borodin:你能解释一下吗?我没有注意到你所说的不良做法;不过,我确实同意变量命名可以改进 (2认同)