0

我有一个名为的 Perl 模块文件genbank.pm,它有一个子程序new;这个 Perl 模块没有使用Exporter也没有定义@EXPORTor @EXPORT_OK。在同一目录中,我有一个名为 的 Perl 文件test.pl,其代码test.pl为:

require 'genbank.pm';
use strict;
our $result = genbank::new();

当我使用 Komodo 运行它时,它会报告:

Undefined subroutine &genbank::new called at /home/mrs/scripts/test.pl line 3;

在我更改代码后

our $result = genbank::new();

our $result = genbank->new();

它说:

Can't locate object method "new" via package "genbank"(perhaps you forgot to load "genbank"?) at /home/mrs/scripts/test.pl line 3.

4

1 回答 1

3

您没有提供足够的信息来完全确定问题所在,但最可能的原因是new子组件位于genbank.

当您尝试调用genbank::new(or ) 时,Perl会在包中而不是在文件中genbank->new查找名为 sub 。按照惯例,该文件将包含一个名为 的包,但这纯粹是为了约定和方便。它不是由语言强制执行的,并且文件名和包名之间绝对没有自动连接。newgenbankgenbank.pmgenbank.pmgenbank

要找出您的潜艇被放置在哪个包中,请查看genbank.pm是否有任何行package xxxx;. 出现在该sub new行之前的最后一个将告诉您new所属的包。如果定义前没有声明,则默认package在包中。main

(如果您负责genbank.pm源代码,我还建议添加package genbank;到文件或重命名文件以匹配它实际包含的包,以避免将来出现这种混淆。)

编辑以回应OP的评论:

由于模块当前以 开头package MRS::Scripts::genbank,那么这new就是创建 sub 的包。您有两种调用它的选项:

  1. 将其称为MRS::Scripts::genbank::new(或者,如果它实际上是一个对象构造函数,则称为MRS::Scripts::genbank->new)。如果你想使用包名来调用它,那么你必须使用正确的包名。

  2. 从包中导出它MRS::Scripts::genbank并修改您的调用脚本以从该包中导入符号(通过移动genbank.pmMRS/Scripts/genbank.pm并更改您的requiretouse MRS::Scripts::genbank; MRS::Scripts::genbank->import;在之后添加require),然后将其调用为new(). 虽然这将在您的问题的有限范围内起作用,但我强烈建议您不要这样做,因为一旦您对另一个包含 a 的模块重复此操作sub new,它就会全部崩溃,因为不能同时有两个news同一个地方。

解决此问题的最简洁方法是移动genbank.pmMRS/Scripts/genbank.pm,将您的更改requirerequire MRS::Scripts::genbank.pm(或use;如果您不导出任何内容,它们是等效的),然后将 sub 称为MRS::Scripts::genbank::newor MRS::Scripts::genbank->new。这种方法将使文件名和包名彼此同步,这将使将来必须维护代码的人(可能是你......)的生活更轻松。

于 2013-08-30T09:24:50.877 回答