Помощь в вызове подпрограммы из модуля Perl и печать в файл журнала - PullRequest
1 голос
/ 18 июля 2011

Я не уверен, как вызвать другую подпрограмму из подпрограммы, объявленной в модуле perl.Подпрограмма просто получает информацию о дате.

У меня есть дескриптор файла, открытый для файла журнала, и я хочу распечатать некоторую информацию о дате в этот файл журнала, но она не распечатывается.Я вижу, что это касается файла, я также сделал файл журнала -rwx.

Вот пример подпрограммы в модуле perl (Test.pm), который я вызываю:

sub spGetCurDateTime {
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
    my $currentDateTime = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
        $year+1900, $mon+1, $mday, $hour, $min, $sec;
    return $curDateTime;
}

Вот часть моего тестового кода, где я пытаюсь вызвать подпрограмму из (Test.pm)

use Test.pm;

#Create log
open (LOG, ">/home/dev/test.log") || die "cannot append";

sub get_alert {
   undef $/;
   open (my $QFH, "< /home/dev/test.sql") or die "error can't open this file $!";
   print LOG "Checking on status time =>", &spGetCurDateTime, "\n";
   my $sth= $dbh->prepare(<$QFH>) ||
      die ("Cannot connect to the database: ".$DBI::errstr."\n");
   $sth->execute;
   close $QFH;
   my $row = $sth->fetchrow_hashref;
   $sth->finish;
   return $row->{RESULT};
   print $row;
}

Ответы [ 3 ]

5 голосов
/ 18 июля 2011

Во-первых, никогда не говорите &functionname, если только вы не знаете, почему вам может понадобиться магическое поведение. В общем, в Perl 5 вызовы функций выглядят как functionname() или functionname в зависимости от того, хотите ли вы, чтобы они рассматривались как термин (т. Е. Наивысший уровень приоритета) или как оператор (это проще, когда вы начинаете просто всегда используйте форму functionname(), так как это сделает то, что вы ожидаете).

Можно сказать

print LOG "Checking on status time =>", Test::spGetCurDateTime(), "\n";

Но это может устареть, поэтому большинство людей используют модуль Exporter для экспорта определенных функций и переменных в пространство имен, в котором указано use Test;. Вы также можете отказаться от использования имени модуля Test, уже существует модуль с таким именем .

В файле T.pm:

package T;

use strict;
use warnings;

use Exporter qw/import/;
our @EXPORT_OK = qw/spGetCurDateTime/;

sub spGetCurDateTime {
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime;
    my $currentDateTime = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
        $year+1900, $mon+1, $mday, $hour, $min, $sec;
    return $currentDateTime;
}

1;

В файле t.pl:

#!/usr/bin/perl

use strict;
use warnings;

use T qw/spGetCurDateTime/;

print spGetCurDateTime(), "\n";
0 голосов
/ 18 июля 2011

Многие пользователи не понимают в Perl namespace .

Без обработки пространства имен что-то вроде CPAN архива модулей Perl было бы невозможно, потому что каждый модуль должен был бы убедиться, что никакие другие модули не имеют подпрограмм и имен переменных, которые есть у любого другого модуля.has.

Стандартным способом написания Perl каждый модуль Perl имеет свое собственное пространство имен.Таким образом, имена и функции переменных не вступают в противоречие с переменными и функциями, которые вы определили в своей программе.

Посмотрите на свой тестовый модуль и посмотрите, есть ли строка:

package Test;

в верхней части программы.Если это так, это означает, что каждая переменная в вашем модуле и каждая подпрограмма находятся в пространстве имен Test, а не в вашем пространстве main (которое является пространством имен по умолчанию).Команда package изменяет пространство имен до следующей команды пакета.

Если (как мы подозреваем) ваш модуль Test.pm имеет команду package, вам нужно обратитьсяк вашей подпрограмме spGetCurDateTime как Test::spGetCurDateTime.

Как уже указывалось, вы можете импортировать переменных и имен функций в текущее пространство имен, используя Exporter .

package Test;
use base qw(Exporter);

our @EXPORT qw(spGetCurDateTime log);

sub spGetCurDateTime {
};

В вашей основной программе:

use Test;

автоматически импортирует подпрограммы spGetCurDateTime и log , и вы можете просто использовать их как spGetCurDateTime() иlog instead of Test :: spGetCurDateTime and Test :: log`.

Однако импорт всех подпрограмм и переменных по умолчанию теперь не рекомендуется, поскольку он может без предупреждения создавать помехи для собственной программы пользователя.В приведенном выше примере я не только импортирую функцию log, но и переопределяю функцию log, встроенную в Perl (log принимает натуральный логарифм числа).

Лучше использовать EXPORT_OK и позволить пользователям выбирать функции, которые они хотят импортировать:

package Test;
use base qw(Exporter);

our @EXPORT_OK qw(spGetCurDateTime log);

sub spGetCurDateTime {
};

В вашей основной программе:

use Test qw(spGetCurDateTime);

Теперь вы можете сделать spGetCurDateTime()вместо Test::spGetCurDateTime, но вы не изменили log, даже не осознав этого.Вы все еще можете сказать Test::log, чтобы выполнить подпрограмму log в вашем модуле.

0 голосов
/ 18 июля 2011

Читайте man perlmod. Вам нужно поместить функцию в качестве экспортируемого символа, полностью квалифицировать ее или импортировать специально ...

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