仅通过加载模块的一部分来节省资源?

时间:2017-04-12 08:49:00

标签: perl perl-module

我正在阅读O'Reilly的Perl Objects,References&模块,更具体地说是关于模块的部分。它指出使用use Some::Module时,您可以指定导入列表。从它的解释看来,使用这个列表的唯一好处是为了保持命名空间的清洁。换句话说,如果您的some_sub包中有子例程main,并且加载的模块有一个同名的子例程,则子例程将被覆盖。但是,如果您指定导入列表并从此列表中省略some_sub,则不会发生此冲突。然后,你可以通过声明它来运行模块中的some_sub:Some::Module::some_sub

除了上面描述的那个之外还有其他好处吗?我问这个是因为在某些情况下你加载带有加载功能的模块,即使你只对它的一些方法感兴趣。起初我认为通过指定一个导入列表,你只加载那些方法,而不是用你不会使用的方法来膨胀内存。但是,从上面的解释看来并非如此。您是否可以通过仅加载模块的部分来有选择地节省资源?或者Perl是否足够聪明,在编译时无需程序员的干预就可以做到这一点?

2 个答案:

答案 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的首选方法是使用Exporterimport方法。

选择性导入减轻了符号表(可能还有一些相关的机制),但我不知道这有什么实际好处。这些好处与编程有关,通过减少碰撞机会。

另一个明显的好处是它可以很好地记录代码中使用的内容。

答案 1 :(得分:4)

请注意,“导入列表”只是一种约定。模块的import函数可以随意使用此列表执行任何操作,您可以看到许多所谓的pragma模块使用它(ab)。因此,部分加载不以任何方式绑定到use。例如,模块可以加载重要的函数存根,无论你是否导入它们,并在实际的第一次调用时动态加载大量的实现。

因此,具有部分导入列表的use可能会或可能不会实际保存任何资源 - 这完全取决于use d模块的实际实现。

虽然requireuse确实加载了整个.pm文件 - 但该文件可能只是一个轻量级的存根和加载器,用于位于其他位置的实际代码。还有一个惯例是调用这些模块::Heavy

模块可以自由地以任何方式实现部分加载。以下是模块如何节省资源的一些可能性:

  1. AUTOLOAD(带有免费的AutoLoader,AutoSplit和SelfLoader模块)。
  2. 使用加载必要子模块的存根。
  3. 首次按名称访问繁重数据(即词典或编码地图)时,动态加载。
  4. 如果您依赖其他重型模块,请在运行时动态require在依赖于它们的函数中,而不是在开始时编译时use
  5. 此列表中的所有内容都可以在幕后自动运行,通过use导入列表公开,或以其他完全任意的方式工作/调用。再一次,它完全取决于模块的实现。