我不确定如何从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;
}
答案 0 :(得分:5)
首先,永远不要说&functionname
,除非你知道为什么你可能想要魔术行为。通常在Perl 5中,函数调用看起来像functionname()
或functionname
,具体取决于您是希望将其视为术语(即最高优先级)还是操作符(当您启动时更容易)我总是使用functionname()
形式,因为这样可以达到预期目的。)
你可以说
print LOG "Checking on status time =>", Test::spGetCurDateTime(), "\n";
但是这可能会变老,所以大多数人使用Exporter
模块将某些函数和变量导出到use Test;
的名称空间中。您可能还希望避免使用模块名称Test
,已经有module with that name。
文件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";
答案 1 :(得分:0)
阅读man perlmod。您需要将该函数作为导出符号,完全限定它,或者专门导入它...
答案 2 :(得分:0)
许多用户对Perl不了解的一件事是 namespace 。
如果不处理名称空间,就不可能像Perl模块的CPAN存档那样,因为每个模块都必须确保没有其他模块具有任何其他模块所具有的子程序和变量名。
以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
函数,而且还覆盖了Perl中内置的log
函数(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
子例程。