让我们说,我们的框架有两个模块:Handler.pm和Queries.pm
Queries.pm是可选的,在fastcgi进程启动时加载
BEGIN {
&{"check_module_$_"} () foreach (Queries);
}
sub check_module_queries {
...
require Eludia::Content::Queries;
...
}
Run Code Online (Sandbox Code Playgroud)
每个模块函数都加载在一个公共命名空间中
现在,Handler.pm和Queries.pm中有两个具有相同名称(setup_page_content)的函数
在Handler.pm中调用setup_page_content
看起来原始作者建议每当加载Queries.pm时都会调用Queries.pm:setup_page_content
有时它不会发生:在这些情况下追溯(通过调用者()获得)表明,setup_page_content是从模块Handler.pm调用的.
我在调用之前记录了%INC,它包含Queries.pm,在这些情况下它是完整路径
这种行为是不一致的,并且在2-3%的生产安装尝试中弹出,主要是当我发送两个并行相同的http请求时.由于重现的努力量,我还没有确定,是否是特定于安装.
如何确定将调用哪个版本的同名函数?
这是明确定义的行为吗?
应该有一个原因,原作者用这种方式编写代码
UPDATE
perl版本是 v5.10.1 built for x86_64-linux-gnu-thread-multi
更新2
Queries.pm装载在check_module_queries发生(BEGIN {}的Eludia.pm),
使用Loader.pm(via use Loader.pm <params>)为每个请求加载
每当加载Custom.pm时,我都想调用Custom.pm:setup_page_content
所以你想Custom::setup_page_content在它存在时打电话.
if (exists(&Custom::setup_page_content)) {
Custom::setup_page_content(...);
} else {
Handler::setup_page_content(...);
}
Run Code Online (Sandbox Code Playgroud)
有时它不会发生.
完全没有关于此的信息使我无法发表评论.码?什么?
有没有办法'卸载'模块,但留在%INC?
加载模块就是运行它.你不能"取消"代码.充其量,您可以手动撤消运行它的一些效果.这是否包括改变%INC完全取决于你.