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