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

Perl重复继承下常量重定义与原型不匹配问题排查

问题:Perl自定义Enum常量重定义错误

致歉:因代码过于复杂无法提供最小复现示例,以下说明问题:

原有基于Perl多重复继承的系统运行正常,我尝试用自定义的Enum类型替换原有的常量集合实现的“枚举”。该Enum可像之前一样生成常量,还能记录常量名称字符串,支持名称与数值互转。

枚举定义与导出(Auth::VerifyStatus.pm)

在Auth::VerifyStatus.pm中通过以下代码创建枚举:

use Enum v1.0.0;
use constant _VERIFY_STATI => Enum->new('VS_STAT', [qw(OK ERR_BAD ERR_INVALID)]);

生成的常量为基名与列表项的拼接,如VS_STAT_OK、VS_STAT_ERR_BAD等。该包支持导出常量与枚举,导出设置如下:

%EXPORT_TAGS = (
    'enums' => [qw(_VERIFY_STATI)],
    'status_enum' => [_VERIFY_STATI->names()],
);

其中names()方法返回Enum生成的常量名称列表。

重新导出常量(Auth::Verifier.pm)

另一包Auth::Verifier.pm中执行use Auth::VerifyStatus v1.7.0 qw(:status_enum);,并重新导出状态常量:

%EXPORT_TAGS = (
'enums' => [qw(Auth::VerifyStatus::_VERIFY_STATI)],
'status_enum' =>
    [map { 'Auth::VerifyStatus::' . $_ }
     Auth::VerifyStatus::_VERIFY_STATI->names()]);

(添加map是为了尝试解决问题时限定包名)

错误现象

调试时运行perl -MAuth::Verifier -de1,在Auth::Verifier的末尾1;之后出现错误:

...
Auth::Verifier ONE
Auth::Verifier::CODE(0x2224de0)(lib/Auth/Verifier.pm:261):
261:    1;
  DB<1> c
Constant subroutine Auth::VerifyStatus::VS_STAT_OK redefined at -e line 0.
        main::BEGIN() called at -e line 0
        eval {...} called at -e line 0
Prototype mismatch: sub Auth::VerifyStatus::VS_STAT_OK () vs none at -e line 0.
        main::BEGIN() called at -e line 0
        eval {...} called at -e line 0
...

(“ONE”是为调试添加在1;前的输出)

Exporter执行时机

两个包的Exporter均在BEGIN块中执行,示例如下:

our (@EXPORT, @EXPORT_OK, %EXPORT_TAGS, @ISA, $VERSION);
BEGIN {
    use Exporter qw(import);
    $VERSION = v1.7.0;
    $DB::single = 1; # trying to debug this
    @ISA = qw(Flags);
    %EXPORT_TAGS = (
...

疑问

我完全不知道如何合理调试(错误均指向line 0),也不知如何修复,是否对Perl要求过高,应改用真正的OO语言?

额外参考:常量创建代码

以下是运行时创建常量的代码,供参考:

# query or add symbol table entry
sub _sym($;$)
{
    my ($name, $val) = @_;

    no strict 'refs';
    unless ($#_ > 0) {
        if (my ($pkg, $sym) = $name =~ /^(.*::)(.+)$/) {
            return ${$pkg}{$sym};
        }
        confess "_sym: invalid $name\n";
    }
    *{$name} = $val;
}

# query or add symbol table entry to package
sub _pkg_sym($$;$)
{
    my ($pkg, $name, $val) = @_;

    unless ($#_ > 1) {
        _sym($pkg . '::' . $name);
    } else {
        _sym($pkg . '::' . $name, $val);
    }
}

# add constant
sub _add_const($$$)
{
    my $v = $_[2];                      # constant value

    unless (_pkg_sym($_[0], $_[1])) {
        _pkg_sym($_[0], $_[1], sub () { $v });
    } else {
        carp "_add_const: $_[1] already defined in $_[0]\n";
    }
}

内容的提问来源于stack exchange,提问作者U. Windl

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 13:55:09