Perl 为什么裸块在打包后不能访问范围外变量和函数?
我想定义一个类,并在裸块中使用Perl 为什么裸块在打包后不能访问范围外变量和函数?,perl,Perl,我想定义一个类,并在裸块中使用is进行测试,如下所示: use Test::More tests => 1; { package Foofle; use parent qw(Animal); sub sound { 'foof' } is( Foofle->speak, "A Foofle goes foof!\n", "An Animal subclass does the right thing"
is
进行测试,如下所示:
use Test::More tests => 1;
{
package Foofle;
use parent qw(Animal);
sub sound { 'foof' }
is(
Foofle->speak,
"A Foofle goes foof!\n",
"An Animal subclass does the right thing"
);
}
我得到了错误未定义的子例程&Foofle::在t/Animal.t调用,所以如果我添加
use Test::More;
在裸块中,则运行正常
或者我将移动到裸块之外
use Test::More tests => 1;
{
package Foofle;
use parent qw(Animal);
sub sound { 'foof' }
}
is(
Foofle->speak,
"A Foofle goes foof!\n",
"An Animal subclass does the right thing"
);
它运行正常。但是为什么裸块不能访问范围外变量?您正在更改块内的包(或命名空间)。Perl中的每个块都创建一个作用域,您可以对包进行作用域更改
在程序开始时,您处于main
包中。您正在use
ing该包中的Test::More,因此is
函数被导入到该包中。这意味着,现在有一个&main::is
,它指向&Test::More::is
切换包后,仍然会加载Test::More,但不会将is
函数导入到新包中。这就是为什么它抱怨找不到&Foofle::is
所以它实际上是关于包的
,而不是块。
进一步阅读:和。您正在更改块内的包(或命名空间)。Perl中的每个块都创建一个作用域,您可以对包进行作用域更改
在程序开始时,您处于main
包中。您正在use
ing该包中的Test::More,因此is
函数被导入到该包中。这意味着,现在有一个&main::is
,它指向&Test::More::is
切换包后,仍然会加载Test::More,但不会将is
函数导入到新包中。这就是为什么它抱怨找不到&Foofle::is
所以它实际上是关于包的
,而不是块。
进一步阅读:and.您的use Test::More
call将标识符is
导入到当前包中。在第一个实现中,这意味着将is
导入脚本的包中,该包可能是main
包。此后,每次在main
包中使用is
,Perl都知道它应该调用Test::More::is
现在,is
一旦切换到其他包,就不再是Test::More::is
的同义词。实际上,您可以尝试这样做:在裸块中调用is()
,但在声明package Foofle
之前。它应该很好用。这不是赤裸裸的街区的罪魁祸首;事实上,你现在的处境不同了
一个选项是在Foofle
包中使用Test::More
,正如您已经尝试过的那样。另一种方法是使用原始实现,但使用完全限定名调用is
:Test::More::is(Foofle->speak,“…”,“…”)
您的使用测试::更多调用将标识符导入当前包中。在第一个实现中,这意味着将is
导入脚本的包中,该包可能是main
包。此后,每次在main
包中使用is
,Perl都知道它应该调用Test::More::is
现在,is
一旦切换到其他包,就不再是Test::More::is
的同义词。实际上,您可以尝试这样做:在裸块中调用is()
,但在声明package Foofle
之前。它应该很好用。这不是赤裸裸的街区的罪魁祸首;事实上,你现在的处境不同了
一个选项是在Foofle
包中使用Test::More
,正如您已经尝试过的那样。另一种方法是使用原始实现,但使用完全限定名调用is
:Test::More::is(Foofle->speak,“…”,“…”)代码>我喜欢你的例子动物。:)我喜欢你的例子。:)