是"使用"在perl传递?

时间:2012-07-09 19:17:41

标签: perl perl-module

package AA;

package BB;
use AA;

package CC;
use BB;

我必须将use AA置于CC中,还是隐含的?

4 个答案:

答案 0 :(得分:9)

你可以use一个模块,只要它之前被某个东西加载。这就是为什么你可以使用其他模块创建的对象而不知道它们是什么对象类型的原因。例如,您可以使用从HTTP::Response方法返回的LWP对象,尽管您自己从未加载HTTP::Response或意识到它是那种对象。但是,use仅导入调用命名空间,因此这些导入不会显示在其他包中(即使您仍然可以使用完整的包规范调用它们)。

您应该use您的包要直接使用的任何模块。也就是说,use您直接创建的对象的模块。

您也不应该依赖其他软件包来为您加载模块。如果有人改变了那些模块,你就会被困在想知道为什么事情会破裂。而且,即使这样,您仍然依赖于模块加载顺序来确保它完成所有工作。

答案 1 :(得分:4)

use执行两项操作:加载模块(如require所示),如果尚未加载,则调用模块的import方法。不确定加载模块或调用方法如何可以传递。

至于你的第二个问题,主要取决于AA是否有import方法。

答案 2 :(得分:1)

package AA;

package BB;
use AA;

package CC;
use BB;

几乎与:

相同
package CC;
use BB;
BEGIN{ require AA }

package CC;
use BB;
use AA ();

这是因为use做了两件事。它使用require加载文件,然后在其上调用import方法。

所以这些是等价的。

use Module qw'LIST';
BEGIN { require Module; Module->import( qw'LIST' ); }

如果包BB不再需要use AA;行,则可能会出现问题,并且会被删除。

答案 3 :(得分:-1)

主要取决于所涉及的模块是面向对象的模块还是使用Exporter在调用包中提供符号的简单模块。

use首先require给定模块,然后调用其import方法。

require首先检查%INC以查看模块是否已成功加载。如果没有,则搜索@INC中的所有路径以查找匹配的模块文件,并且第一个匹配加载相当于do

模块import方法可以执行作者关心编写的任何操作,但通常一个模块将子类化Exporter,它提供import方法,除其他外,复制符号包的@IMPORT数组到调用包,使符号可用,而不用包名完全限定它们。

在您的示例中,如果模块子类Exporter@BB::IMPORT中列出的符号将被复制到CC命名空间,并可以从该包中使用。但是没有从AA导入任何内容,因此只能通过显式调用它们AA::subroutine()等来调用那里的子程序。

另一方面,如果包是面向对象的模块和BB子类AA,那么通常没有import方法可以调用,并且通过祝福来访问方法变量或类名(包名)。 BB中未定义的方法可以继承自AA,而Perl的面向对象继承系统的实现使用包的@ISA数组来确定继续搜索方法的位置。

总结一下,如果您的模块BB子类Exporter,那么您还必须use AA。但如果它是面向对象的子类AA,那么BBAA中的所有方法都可以CC使用use BB