package AA;
package BB;
use AA;
package CC;
use BB;
我必须将use AA
置于CC中,还是隐含的?
答案 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
,那么BB
和AA
中的所有方法都可以CC
使用use BB
。