没有包或对象引用就无法调用方法“ import”

时间:2018-07-03 11:18:12

标签: perl cgi

我的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

    ...
}

1 个答案:

答案 0 :(得分:3)

这里发生的是import不是内置的Perl函数。相反,它是一个methoduse通常在加载后 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);

间接对象语法通常在printprint $filehandle $output指向文件句柄时使用,但除此之外,它的使用已被淘汰,原因之一是您在这里观察到的令人困惑的语法问题。

您可以使用B::Deparse来查看Perl如何解释您的源代码:

$ perl -MO=Deparse,-p -e 'import $projectID . "/" . $gTable;'
(($projectID->import . '/') . $gTable);

收到该错误消息的原因是,在v5.18之前的Perl版本(引用:bugcommitdelta)上,该字符串位于->必须是已知名称,或以字母数字字符开头。 (尽管从v5.18开始,从理论上讲您可以说"0689/vg76"->import,但正如我在上文中所解释的那样,这几乎肯定不是您想要的。)