You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Perl会尝试重新加载已载入内存的同名模块?

问题核心原因

use base 的内部实现逻辑决定了它会尝试加载指定父类的模块文件,哪怕内存中已经存在同名包的定义。


具体原理

Perl 全局哈希 %INC 是用来记录已经成功加载的模块的,只有当 %INC 中存在 'A.pm' => 1 这类对应记录时,才会认为 A 模块已经完成加载,不需要再从磁盘读取。
你在测试文件中直接写 package A; 只是在进程符号表中创建了 A 包的命名空间,并没有更新 %INC 哈希,因此 use base 'A' 执行时会判定A模块未加载,触发 require 'A.pm' 逻辑,按照 @INC 路径顺序查找文件,刚好匹配到你项目中自带的 A.pm,而该文件依赖的 Mojo::Base 不在测试环境的依赖中,就触发了报错。


解决方法

如果是自己写测试遇到这类场景,有两种通用方案:

  • 改用 parent 模块替代 base,添加 -norequire 参数跳过文件加载逻辑:
    use parent -norequire, 'A';
    
  • 手动标记模块已加载,在你声明完 package A; 后添加一行代码:
    $INC{'A.pm'} = 1;
    
    这行代码会伪装 A.pm 已经被加载过,base 模块就不会再尝试从磁盘读取文件。

如果是安装 Test::Deep 时触发的这个报错,你可以临时将项目自定义的 lib 目录从 @INC 中移除后再执行安装,避免测试用例误加载你本地的同名模块。


内容的提问来源于stack exchange,提问作者Eugen Konkov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 14:51:02