从我的主程序中,我需要一个包含包的文件,然后从那个包中调用一个子例程:
while($somecondition){
require( 'people.pm' );
my $result = PERSON::stuff($args);
}
PERSON包声明了多个subs和一些'our'变量:
package PERSON;
our $name;
our ...
sub stuff {
...
}
在我的理解中,其他更多的面向对象语言需要声明一个新的对象示例,可能需要它自己的构造函数/初始化函数来使用“包”变量,但Perl似乎不是这样。
我处理的是遗留代码,所以我不想做太多修改,我只想了解包变量($name)是什么时候出现的,以及从主程序的Angular 来看,它们是什么时候返回到内存的。
在while循环后调用PERSON::stuff()会不会产生新的包变量?在调用包内的单个函数后,包变量会一直存在到程序结束吗?
2条答案
按热度按时间s4n0splo1#
这个问题混淆了一些概念,所以让我们首先解决看起来是主要问题的问题:如果一个包在某个范围内是
require
'd,那么在该范围之外又是什么呢?简而言之,包中的(动态全局)符号可以通过它们的完全限定名在
require
'd的单元中的任何地方访问。†让我们举个例子
文件
TestPack.pm
:我们需要为这些符号使用完全限定的名称,因为它们没有被导入。如果包导出符号,我们导入一些‡,那么它们会进入调用包的名称空间,所以在上面的例子中,它们会在
main::
中可用,所以解释器中的任何代码都可以通过它们导出的名称访问它们(hi
,不需要TestPack::hi
).不能从那个包访问词法变量(用my
,our
,state
创建)§.如果我们引入另一个包,而不是仅仅块(名为
TEST_SCOPE
),并且require
是我们的TestPack
,那么这也是有效的。(That
package
实际上应该在BEGIN
块中,这并不改变这里的要点。)TestPack
中的全局符号仍然可以在main::
中通过它们的完全限定名访问。导出的名称,我们与require
沿着导入,然后可以在 * 此包 * 中使用,但在main::
中不可用。PERSON
)及其文件名(person.pm
)* 必须一致 *。例如,命名空间(==软件包)Person
在文件Person.pm
中定义所以是的,要在
require
-艾德作用域之外使用这个包,你需要在另一个作用域中示例化一个对象,这仍然和上面的例子很像--我们 * 可以 * 在需要它的作用域之外使用这个包名来示例化一个对象(try!),即使我会提出这样的设计问题(见下一节)require
)将包引入作用域;上下文是什么?(我希望它不是真的在while
循环中。)†打印出main的符号表
%main::
(例如使用Data::Dumper
),我们得到沿着来自
TestPack
命名空间的所有其他符号。‡如果一个包导出符号,我们
require
这个包,那么我们可以导入§注意
our
创建了一个词法变量,它是包变量的别名,* 是 * 可访问的。uwopmtnx2#
zdim's answer很好地解释了包变量是如何工作和使用的,但我不认为它直接回答了它们何时超出范围的问题。
简而言之:
你还问:
在我的理解中,其他更多的面向对象语言需要声明一个新的对象示例,可能需要它自己的构造函数/初始化函数来使用"包"变量,但Perl似乎不是这样。
包变量与Perl中的面向对象编程完全无关,它们不用于存储示例数据(除了有时候由内而外的对象,尽管这是一个更高级的主题)。