2013-08-30 4 views
0

У меня есть файл модуля Perl с именем genbank.pm, он имеет подпрограмму new; этот модуль Perl не использовал Exporter и не определял @EXPORT или @EXPORT_OK. В том же каталоге, у меня есть файл Perl с именем test.pl, код test.pl является:Почему я не могу вызвать функцию модуля после того, как он был успешно использован или успешно использован?

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

Когда я запускаю его с Комодо, он сообщает:

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.

+0

Что происходит, когда вы используете genbank; 'вместо' require ...'? Внутри 'genbank.pm', есть ли' пакет genbank', 'декларация в верхней части? – amon

+0

Нет, объявление пакета в genbank.pm является «пакетом MRS :: Scripts :: genbank», это единственное объявление пакета в файле genbank.pm. Итак, что дальше? – wuchang

+0

Не имеет значения, чтобы перейти от «require ...» к «use ...». – wuchang

ответ

3

Вы не предоставили достаточно информации, чтобы быть полностью уверенным в проблеме, но наиболее вероятной причиной является то, что new к югу находится в пакете, кроме genbank.

При попытке вызова genbank::new (или genbank->new), Perl ищет замену имени new в пакете genbank, не в файле genbank.pm. По соглашению, файл genbank.pm будет содержать пакет с именем genbank, но это исключительно вопрос согласия и удобства. Это не, введенный в действие этим языком, и существует абсолютно нет автоматическое соединение между именами файлов и именами пакетов.

Чтобы узнать, в какой упаковке размещены ваши подсайты, посмотрите на genbank.pm для любых строк, содержащих package xxxx;. Последний, который появится перед линией sub new, сообщит вам пакет, к которому принадлежит new. Если перед его определением нет инструкции package, она по умолчанию будет в пакете main.

(Если вы несете ответственность за исходный код genbank.pm, я бы также предложил либо добавить package genbank; в файл, либо переименовать файл в соответствии с пакетом, который он фактически содержит, чтобы избежать такого рода путаницы в будущем.)

Редактировать в ответ на комментарий OP в:.

Поскольку в настоящее время модуль начинается с package MRS::Scripts::genbank, то это уПАКОВКИ new югу создается у вас есть два варианта для вызова его:

  1. Назовите его MRS::Scripts::genbank::new (или, если он фактически является конструктором объекта, MRS::Scripts::genbank->new). Если вы хотите называть его с помощью имени пакета, вы должны использовать правильное имя пакета.

  2. Экспорт его из MRS::Scripts::genbank пакета и изменить вызывающий скрипт для импорта символов из этого пакета (либо путем перемещения genbank.pm к MRS/Scripts/genbank.pm и изменение require к use MRS::Scripts::genbank;или путем добавления MRS::Scripts::genbank->import; после require), а затем вызвать его как только new(). Хотя это будет работать в рамках ограниченного объема вашего вопроса, я рекомендую против, потому что, как только вы повторите это с другим модулем, содержащим sub new, все будет разваливаться, так как не может быть двух new s на в то же время в одном и том же месте.

Чистейшая способ решить эту проблему будет двигаться genbank.pm к MRS/Scripts/genbank.pm, изменить ваш require к require MRS::Scripts::genbank.pm (или use, если вы ничего не экспортируют, они эквивалентны), а затем вызвать к югу, как MRS::Scripts::genbank::new или MRS::Scripts::genbank->new. Такой подход позволит синхронизировать имя файла и имя пакета друг с другом, что облегчит жизнь тем, кто должен поддерживать код в будущем (что, вероятно, будет вам ...).

+0

Да, объявление пакета - это пакет MRS :: Scripts :: genbank " . Это заявление лежит в первой строке файла genbank.pm, и это единственное объявление пакета. Итак, что мне делать дальше? – wuchang

+0

После того как я изменил объявление пакета из «пакета MRS :: Scripts :: genbank» в простой «пакетный банк», звонок работает. Итак, мой вопрос: что я могу сделать, чтобы сделать звонок успешным, а с другой стороны сохранить декларацию пакета как «пакет MRS :: Scripts :: genbank»? – wuchang

+0

@ Vico_Wu Я отредактировал свой ответ, чтобы объяснить, как сделать эту работу, учитывая дополнительную информацию в вашем комментарии. –

Смежные вопросы