我正在阅读O'Reilly的Perl Objects,References&模块,更具体地说是关于模块的部分。它指出使用use Some::Module
时,您可以指定导入列表。从它的解释看来,使用这个列表的唯一好处是为了保持命名空间的清洁。换句话说,如果您的some_sub
包中有子例程main
,并且加载的模块有一个同名的子例程,则子例程将被覆盖。但是,如果您指定导入列表并从此列表中省略some_sub
,则不会发生此冲突。然后,你可以通过声明它来运行模块中的some_sub:Some::Module::some_sub
。
除了上面描述的那个之外还有其他好处吗?我问这个是因为在某些情况下你加载带有加载功能的模块,即使你只对它的一些方法感兴趣。起初我认为通过指定一个导入列表,你只加载那些方法,而不是用你不会使用的方法来膨胀内存。但是,从上面的解释看来并非如此。您是否可以通过仅加载模块的部分来有选择地节省资源?或者Perl是否足够聪明,在编译时无需程序员的干预就可以做到这一点?
答案 0 :(得分:5)
从use我们看到use Module LIST;
意味着
BEGIN { require Module; Module->import( LIST ); }
另一方面,来自require
否则,
require
要求包含库文件(如果尚未包含)。该文件通过do-FILE机制包含,[...]
和do 'file'
执行'file'
作为Perl脚本。因此,使用use
我们加载整个模块。
“导入”一个子意味着它的名称在调用者的symbol table中添加(或覆盖)(通过类型地球的CODE
插槽,通常是别名),由包{{1}功能。子代码不会被复制。现在,import
可以按照作者想要的任何方式编写,但通常import
语句中的导入列表仅控制将哪些符号带入命名空间。在模块中提供use
的首选方法是使用Exporter的import
方法。
选择性导入减轻了符号表(可能还有一些相关的机制),但我不知道这有什么实际好处。这些好处与编程有关,通过减少碰撞机会。
另一个明显的好处是它可以很好地记录代码中使用的内容。
答案 1 :(得分:4)
请注意,“导入列表”只是一种约定。模块的import
函数可以随意使用此列表执行任何操作,您可以看到许多所谓的pragma模块使用它(ab)。因此,部分加载不以任何方式绑定到use
。例如,模块可以加载重要的函数存根,无论你是否导入它们,并在实际的第一次调用时动态加载大量的实现。
因此,具有部分导入列表的use
可能会或可能不会实际保存任何资源 - 这完全取决于use
d模块的实际实现。
虽然require
和use
确实加载了整个.pm
文件 - 但该文件可能只是一个轻量级的存根和加载器,用于位于其他位置的实际代码。还有一个惯例是调用这些模块::Heavy
。
模块可以自由地以任何方式实现部分加载。以下是模块如何节省资源的一些可能性:
require
在依赖于它们的函数中,而不是在开始时编译时use
。此列表中的所有内容都可以在幕后自动运行,通过use
导入列表公开,或以其他完全任意的方式工作/调用。再一次,它完全取决于模块的实现。