同一文件不同包中导入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
相关产品推荐
相关产品推荐

