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

同一文件不同包中导入Type::Library声明的类型为何失败?

问题原因与解决方法

你的代码无法运行的核心原因是:手动创建的Type::Tiny对象没有关联到Types::Mine类型库,导致Type::Library的导出机制无法识别这个类型,也就无法生成对应的导出子例程Number。

具体问题分析

当你直接用Type::Tiny->new创建类型对象时,这个对象默认不属于任何类型库。即便你通过__PACKAGE__->meta->add_type($NUM)将它添加到库的元数据中,Type::Library基于Exporter::Tiny的导出系统依然无法将其识别为可导出的符号——因为类型对象缺少与当前库的关联信息。

解决方法

方法一:为Type::Tiny对象指定library属性

在创建Type::Tiny对象时,显式指定library属性为当前包,让类型与库建立关联:

package Types::Mine {
   use Scalar::Util qw(looks_like_number);
   use Type::Library -base;
   use Type::Tiny;

   my $NUM = Type::Tiny->new(
      name       => "Number",
      library    => __PACKAGE__, # 新增:关联到当前类型库
      constraint => sub { looks_like_number($_) },
      message    => sub { "$_ ain't a number" },
   );

   __PACKAGE__->meta->add_type($NUM);

   __PACKAGE__->meta->make_immutable;
}

方法二:使用Type::Library的add_type方法直接创建类型

这是更简便的标准写法,Type::Library会自动处理类型与库的关联,无需手动创建Type::Tiny对象:

package Types::Mine {
   use Scalar::Util qw(looks_like_number);
   use Type::Library -base;

   __PACKAGE__->add_type(
      name       => "Number",
      constraint => sub { looks_like_number($_) },
      message    => sub { "$_ ain't a number" },
   );

   __PACKAGE__->meta->make_immutable;
}

验证修改后的代码

修改后,main包中的导入代码就能正常运行,Number子例程会被正确导入,执行后会输出类型对象的字符串表示(类似Types::Mine::Number)。

内容的提问来源于stack exchange,提问作者Evan Carroll

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:05:26