【问题标题】:Perl module dependency organization and include orderPerl 模块依赖组织和包含顺序
【发布时间】:2015-01-20 13:07:28
【问题描述】:

我知道 perl 中的循环模块依赖性以及这是一个非常糟糕的主意,例如:

package ModuleA;
use ModuleB;

package ModuleB;
use ModuleA;

我想问一下以下模型是否安全,是否遵循一些最佳实践规则:

package main;
use ModuleA;
use ModuleB;

package ModuleA;
use ModuleB;
use ModuleC;

package ModuleB;
use ModuleC;

另外我想问一下use-ing模块的顺序是否有影响?例如如果

package main;
use ModuleA;
use ModuleB;

相同
package main;
use ModuleB;
use ModuleA;

如果

package ModuleA;
use ModuleB;
use ModuleC;

相同
package ModuleA;
use ModuleC;
use ModuleB;

等等

编辑: 请注意,ModuleA 显式加载 ModuleC(并且不依赖 ModuleB 来加载 ModuleC),因为 ModuleA 使用 ModuleC 中的函数。这是好的设计方法吗?

【问题讨论】:

  • 信息不足。这些是OO模块、功能模块、语用模块吗?它们是基于 Exporter 的吗?
  • 是的,他们正在使用 Exporter。我认为每个模块都包含程序代码。你能解释一下为什么这很重要吗?
  • 因为use = require + import。 OO 模块通常没有import,非Exporter 模块可能有一个狂野的import
  • 请问您所说的“狂野import”是什么意思。此外,当您有我提到的依赖项时(并且还满足显式加载所需模块的条件,例如 ModuleA 显式加载 ModuleC 并且不依赖 ModuleB 它将加载 ModuleC)是否可以,或者是否有一些信号表明脚本应该重新设计面向对象或功能或什么?
  • "wild" import 可以做任何事情:在调用者的命名空间中创建随机 subs、设置全局变量、安装信号处理程序、覆盖核心函数等。

标签: perl module perl-module


【解决方案1】:

最佳实践很简单:每个文件、程序或模块都应指定其所有依赖项。就是这样。例如,如果一个脚本需要模块 A 和 B,而模块 A 需要模块 B,则不要指望脚本已经加载了模块 B - 如果其他脚本需要模块 A 而不需要 B,该怎么办?

良好的基于​​导出器的模块应该使用@EXPORT_OK,并且您应该在 use 子句中明确列出导入的子例程。它有助于防止名称冲突。

对于只导出子程序的普通模块,顺序无关紧要。但在其他情况下,它可能会:考虑

use warnings_;
use diagnostics;

use diagnostics;
use warnings_;

【讨论】:

  • 顺序确实很重要,具体取决于模块,尤其是对于导入子例程的模块。发生冲突时,最后一个获胜。
  • @choroba "如果一个脚本需要模块 A 和 B,而模块 A 需要模块 B" "如果其他脚本需要模块 A 而不需要模块 B怎么办?"这两种说法不是互斥的吗?当我有模块 A 时,在哪里明确表示它 use 模块 B(没有 B,A 无法工作)怎么可能有人想使用模块 A 而不是模块 B?换句话说,当模块 A 被加载并且它不能被改变时,模块 B 被显式加载,或者可以?使用@EXPORT_OK 是什么意思?如果我理解你是正确的,你说模块 A 应该包含在模块 B 的 @EXPORT_OK 子例程中?
  • @WakanTanka:“使用”是指use,即脚本C包含use A;,但不包含use B;,因为处理其依赖关系是A的责任。跨度>
  • 所以基本上你是说所有需要的模块都应该被显式加载,不要依赖于它们会被另一个使用它们的模块丢失的事实,对吗?这是否被认为是最佳实践?谢谢
  • @WakanTanka:没错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 2013-11-05
  • 1970-01-01
  • 1970-01-01
  • 2014-02-10
  • 1970-01-01
相关资源
最近更新 更多