嵌套子程序和范围界定在Perl(Nested subroutines and Scoping in

2019-06-23 17:08发布

我现在很长一段时间写的Perl,总是发现新的东西,我只是碰到了一些有趣的事情,我没有解释它,也没有发现它在网上。

sub a {
   sub b {
     print "In B\n";
   }
}
b();

我怎么就可以调用b()从它的范围之内,它的工作原理?

我知道它不好的做法去做,我不这样做,我用合拢和这样对于这些情况,只是看到了。

Answer 1:

子程序是存储在编译时一个全局命名空间。 在你的榜样b(); 为短针main::b(); 。 为了限制功能的知名度,你需要分配一个匿名子程序变量的作用域。

两个命名和匿名子程序可以形成封闭,但如果你嵌套它们尽可能多的人希望他们不循规蹈矩,因为命名的子程序只能编译一次。

use warnings;
sub one {
    my $var = shift;
    sub two {
        print "var: $var\n";
    }
}
one("test");
two();
one("fail");
two();
__END__
output:
Variable "$var" will not stay shared at -e line 5.
var: test
var: test

嵌套命名的子程序被允许在Perl,但它几乎可以肯定的是,代码被错误地做成才的标志。



Answer 2:

下面打印123

sub a {
    $b = 123;
}

a();
print $b, "\n";

那么,为什么是你惊讶的是,下列情况呢?

sub a {
    sub b { return 123; }
}

a();
print b(), "\n";

任何地方都没有提出任何要求$b&b是词汇。 事实上,你不能要求&b是词汇(还)。

sub b { ... }

基本上是

BEGIN { *b = sub { ... }; }

其中, *b是符号表项$b@b ,......,当然还有&b 。 这意味着潜艇属于包,从而可以从任何地方的包中被调用,或在任何地方,如果全部使用他们的完全合格的域名( MyPackage::b()



Answer 3:

“官方”的方式在Perl创建嵌套子例程是使用local关键字。 例如:

sub a {
    local *b = sub {
        return 123;
    };
    return b();  # Works as expected
}

b();  # Error: "Undefined subroutine &main::b called at ..."

该perldoc页也perlref有这个例子:

sub outer {
    my $x = $_[0] + 35;
    local *inner = sub { return $x * 19 };
    return $x + inner();
}

“这具有地方到另一个函数的函数的有趣的效果,一些不能正常使用Perl的支持。”



Answer 4:

子程序是在编译时间定义,而不受范围。 换句话说,他们不能真正嵌套。 至少不会就自己的范围而言。 被定义后,将它们有效地从源代码移除。



文章来源: Nested subroutines and Scoping in Perl