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

Bra*_*roy 6 perl perl-module

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

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

zdi*_*dim 5

使用中我们看到的use Module LIST;确切意味着

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

另一方面,来自要求

否则,require要求包含库文件(如果尚未包含库文件).该文件通过do-FILE机制包含,[...]

并作为Perl脚本do 'file'执行'file'.因此,use我们加载整个模块.

"导入"子表示通过包的函数在调用者的符号表中添加(或覆盖)其名称(通过CODEtypeglob 的插槽,通常是别名)import.子代码不会被复制.现在,import可以按照作者想要的任何方式编写,但通常use语句中的导入列表仅控制将哪些符号带入命名空间.import在模块中提供的首选方法是使用Exporterimport方法.

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

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


Ole*_*kov 4

请注意,“导入列表”只是一种约定。模块的import功能可以自由地使用此列表执行任何操作,您可以看到它被许多所谓的编译指示模块使用(滥用)。因此,部分加载不受use任何方式的约束。例如,模块可以加载繁重的函数存根,无论您是否导入它们,并在实际第一次调用时动态加载繁重的实现。

因此use,部分导入列表实际上可能会或可能不会节省任何资源 - 这完全取决于used 模块的实际实现。

虽然require确实use加载了整个.pm文件 - 该文件很可能只是位于其他地方的实际代码的轻量级存根和加载器。还有另一种约定来称呼这些模块::Heavy

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

  1. AUTOLOAD(及其免费的 AutoLoader、AutoSplit 和 SelfLoader 模块)。
  2. 使用加载必要子模块的存根。
  3. 当首次按名称访问大量数据(即字典或编码映射)时,动态加载它们。
  4. 如果您依赖于其他重型模块,require请在运行时在依赖它们的函数中动态地调用它们,而不是use从一开始就在编译时进行。

该列表中的所有内容都可以在幕后自动工作,通过use导入列表公开,或者以其他完全任意的方式工作/被调用。再次强调,这完全取决于模块的实现。