Невозможно вызвать метод import без ссылки на пакет или объект - PullRequest
0 голосов
/ 03 июля 2018

Моя программа Perl CGI использует функцию import, я вызываю файл .pm.

В следующем коде, когда $projectID является строкой, например "try", ошибок импорта нет. Но если он числовой - например, "0689" - затем появляется следующая ошибка

Невозможно вызвать метод import без ссылки на пакет или объект в строке aa.cgi 993.

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 голосов
/ 04 июля 2018

Здесь происходит то, что import является , а не встроенной функцией Perl. Вместо этого это метод , который use обычно вызывает пакет после его загрузки - кажется, вы пытаетесь вызвать его на имя файла , которое не будет работать.

Полагаю, вы пытаетесь динамически загрузить пакет на основе содержимого этих переменных. Вот один из нескольких способов сделать это:

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 интерпретирует его как Синтаксис косвенного объекта , где 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);

Причина, по которой вы получаете это сообщение об ошибке, состоит в том, что в версиях Perl до v5.18 (ссылки: ошибка , commit , delta ), Строка слева от -> должна была быть известным именем или начинаться с буквенно-цифрового символа. (И хотя в версии 5.18 вы можете теоретически сказать "0689/vg76"->import, это почти наверняка не то, что вы хотите, как я объяснил выше.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...