我的Perl CGI程序使用import
函数,我正在调用.pm
文件。
在以下代码中,当$projectID
是字符串(例如"try"
)时,没有导入错误。但如果是数字,例如"0689"
-然后出现以下错误
在aa.cgi第993行没有包或对象引用的情况下,无法调用方法“ import”。
my $projectID = "0689"
my $gTable = "vg" . $tm . ".pm";
my $new_vPath = $hconfig::usersPNG . $vnm;
my $gen_listPath = $usersTMP . $gTable;
if ( -e $new_venPath && -e $gen_listPath ) {
require $projectID . '/' . $gTable;
import $projectID . '/' . $gTable; # try2/vg77.pm -> no error # 0689/vg76.pm -> import error
...
}
答案 0 :(得分:3)
这里发生的是import
不是内置的Perl函数。相反,它是一个method,use
通常在加载后 package 上调用-您似乎试图在文件名,将无法正常工作。
我想您正在尝试根据这些变量的内容动态加载程序包。这是几种方法之一:
my $filename = '/path/to/Package/Name.pm';
my $packagename = 'Package::Name';
require $filename;
$packagename->import();
要像这样动态加载模块要记住的一件事是,与use
加载的模块不同,Perl在编译时不会知道从那些包导出的函数。结果是您不能在对这些函数的调用中省略括号。
因此,例如:如果您有一个模块Foo
可以导出函数foo
,则可以说:use Foo; foo "bar";
。但是,如果您用上述代码加载Foo
,则必须说foo("bar");
。
顺便说一句,我怀疑0689::vg76
是您的一个软件包的名称。如果您可以详细说明您要尝试加载的内容,即文件0689/vg76.pm
的样子以及从文件中加载的内容(例如,它们实际上有一个sub import
吗?),也许我们可以建议一种更合适的加载方式。
import $projectID . '/' . $gTable;
仍然是有效语法的原因是Perl将其解释为Indirect Object Syntax,其中method_name $object @parameters;
被视为$object->method_name(@parameters);
。
间接对象语法通常在print
中print $filehandle $output
指向文件句柄时使用,但除此之外,它的使用已被淘汰,原因之一是您在这里观察到的令人困惑的语法问题。
您可以使用B::Deparse
来查看Perl如何解释您的源代码:
$ perl -MO=Deparse,-p -e 'import $projectID . "/" . $gTable;'
(($projectID->import . '/') . $gTable);
收到该错误消息的原因是,在v5.18之前的Perl版本(引用:bug,commit,delta)上,该字符串位于->
必须是已知名称,或以字母数字字符开头。 (尽管从v5.18开始,从理论上讲您可以说"0689/vg76"->import
,但正如我在上文中所解释的那样,这几乎肯定不是您想要的。)