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

Perl自定义模块函数导入问题:调用person_init时报未定义子例程错误

解决Perl自定义模块导入函数的错误问题

首先,咱们来看你遇到的错误:Undefined subroutine &main::person_init called(你提供的错误信息里写的是Person_Init,应该是笔误,实际是小写的person_init),根源主要是模块包名和目录结构不匹配导致的。

问题分析

你的目录结构是:

TestObject.pl
Person/
  Person.pm
  PersonInit.pm

Perl对模块的包名有严格要求:包名必须和文件所在的目录结构对应。比如:

  • Person/Person.pm 的包名是 Person(这部分你已经写对了)
  • Person/PersonInit.pm 的包名应该是 Person::PersonInit,但你现在写的是 package PersonInit;——这就导致Perl无法正确关联模块路径和包名,use Person::PersonInit; 加载的模块实际属于PersonInit包,导出的函数也在这个包下,主脚本的main包自然找不到这个函数。

修复步骤

1. 修正PersonInit.pm的包名

打开Person/PersonInit.pm,把第一行的包名改成:

package Person::PersonInit;

2. (可选)简化模块内的库路径设置

你的主脚本TestObject.pl已经通过use lib $RealBin;设置了正确的库路径,所以PersonInit.pm里的use FindBin和use lib可以去掉(留着也不影响,但没必要重复设置)。修改后的开头部分如下:

#!/usr/bin/perl
package Person::PersonInit;
use strict;
use POSIX;
use warnings;
use Person::Person;
use Exporter;
our @ISA= qw( Exporter );
our @EXPORT_OK = qw( person_init );
our @EXPORT = qw( person_init );

3. 确认函数调用的大小写一致性

Perl是大小写敏感的,确保你在TestObject.pl里调用的是person_init()(全小写),和模块里定义的函数名完全一致(你的代码里已经是对的,只要别写成Person_Init就好)。

测试修复

现在重新运行TestObject.pl,应该就能正确调用person_init函数了。这个函数会创建一个Person对象,打印默认的nom值(inconnu)和toto,然后主脚本再打印toto,最终输出应该是:

inconnutotototo

额外小建议

模块里的对象属性(比如_NOM、_PRENOM)最好通过访问器方法(getter/setter)来访问,而不是直接读取哈希键,这样更符合面向对象的封装原则。比如在Person.pm里添加:

sub get_nom {
    my ($self) = @_;
    return $self->{_NOM};
}

之后在PersonInit.pm里就可以用$Person->get_nom()代替$Person->{_NOM}啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:00:53