我们有一个基于Perl的大型网站。
我被分配来重构许多脚本和包的代码。有时候更改很简单,我只修改现有的功能。但有时我需要重写整个函数。我重写的函数调用其他函数的坏消息。因此,如果我在新模块中移动重构代码,我还需要复制所有补充功能。但是,如果我不将重构代码移动到我的特殊模块,一个微小的语法错误可能会导致整个站点崩溃: - (
是的,我知道我们应该使用版本控制等等。但我们不这样做,这是一个我无法改变的事实。怎么办?
所以我需要在Test模块中保留一些代码(以避免语法错误导致整个站点崩溃)。是否可以从其他模块进行循环引用测试(对于我的新重构例程)以及从Test到其他模块(用于补充例程)?
请注意,我们的大多数脚本和模块都需要一些AutoRequire
模块。 AutoRequire
使A :: X()调用自动加载A模块(如果尚未加载)。
我的主要问题是在此设置中是否可以使用相互模块依赖项。还有其他建议吗?
答案 0 :(得分:1)
要求工作首先检查模块是否已经加载,如果没有加载,然后将其标记为已加载。因此,如果你有一个依赖,Foo要求Bar和Bar需要Foo,它将首先尝试加载Foo,在Foo中尝试加载Bar。但由于Bar要求Foo和Bar尚未最终加载,否则会产生问题。
从@ysth输入后编辑:它不会失败,但它可能只是部分加载某些东西,这可能会在以后引起有趣的问题。
所以它可能会起作用,但它也可能会在以后出现问题(比如无法使用导出的函数等)。
答案 1 :(得分:0)
Perl允许相互依赖,但它们有时会导致不直观的行为。我given before的一个例子是:
<强> foo.pm 强>
package foo;
use bar;
sub import { printf("%s loaded foo\n", scalar caller) }
1;
<强> bar.pm 强>
package bar;
use foo;
sub import { printf("%s loaded bar\n", scalar caller) }
1;
<强> script.pl 强>
#!/usr/bin/env perl
package main;
use foo;
输出:
foo loaded bar
main loaded foo
您是否希望在该输出中的某处看到bar loaded foo
?
仔细考虑编译时间与运行时间等等,您将意识到为什么不输出该行,并且这是正确的和记录的行为。不一定非常直观。
也就是说,对于纯粹的面向对象的模块,它们在导入时不做任何事情(例如将任何东西输出到它们的调用者,或者作为一个pragma,或者像在这个例子中那样 - 打印输出),它通常应该很漂亮安全
也就是说,对于纯粹面向对象的模块,通常没有理由先使用use
预先加载它们 - 而是在需要时可以使用require
或Module::Runtime加载它们。