I'm not sure how to call another subroutine from a sub declared in a perl module. The subroutine is simply getting date information.
I have a file handle open for a log file and I want to print out some date information to this logfile, but its not printing out. I can see that it touches the file, I made the log file -rwx too.
Here is the sample subroutine in perl (Test.pm) module that I am calling:
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;
}
Here's part of my test code where I am trying to call the subroutine from (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->pre开发者_如何学Pythonpare(<$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;
}
First, never say &functionname
unless you know why you might want magic behavior. In general in Perl 5, function calls look like functionname()
or functionname
depending on whether you want it treated as a term (i.e. the highest level of precedence) or an operator (it is easier when you are starting out to just always use the functionname()
form since that will do what you expect it to).
You can say
print LOG "Checking on status time =>", Test::spGetCurDateTime(), "\n";
But that can get old, so most people use the Exporter
module to export certain functions and variables into the namespace that said use Test;
. You may also wish to avoid using the module name Test
, there is already a module with that name.
In the file 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;
In the file t.pl:
#!/usr/bin/perl
use strict;
use warnings;
use T qw/spGetCurDateTime/;
print spGetCurDateTime(), "\n";
Read man perlmod. You need to put the function as an exported symbol, fully qualify it, or import it specifically...
One of the things many users don't understand about Perl is namespace.
Without handling namespace, something like the CPAN archive of Perl modules would be impossible because each and every module would have to make sure that no other modules have subroutines and variable names that any other module has.
In the standard way Perl is written, each Perl module has its own namespace. That way, variable names and functions don't collide with variables and functions you have defined in your program.
Take a look at your Test module, and see if there's a line:
package Test;
in the top of the program. If it does, it means each variable in your module and each subroutine is in the namespace of Test
and not your main
namespace (which is the default namespace). The package command changes the namespace until the next package command.
If, (as we suspect), your Test.pm module has the package
command, you'll need to refer to your spGetCurDateTime
subroutine as Test::spGetCurDateTime
.
As has already been pointed out, you can import variables and function names into the current namespace by using Exporter.
package Test;
use base qw(Exporter);
our @EXPORT qw(spGetCurDateTime log);
sub spGetCurDateTime {
};
In your main program:
use Test;
will automatically import your spGetCurDateTime and log subroutines, and you can simply use them as spGetCurDateTime()
and log instead of
Test::spGetCurDateTimeand
Test::log`.
However, default importing of all subroutines and variables is now discouraged since it can interfere with the user's own program without warning. In the above example, I'm not only importing the log
function, but I am also overriding the log
function that's built into Perl (log
takes the natural logarithm of a number).
Better, is to use EXPORT_OK
and let users select the functions they want to import:
package Test;
use base qw(Exporter);
our @EXPORT_OK qw(spGetCurDateTime log);
sub spGetCurDateTime {
};
In your main program:
use Test qw(spGetCurDateTime);
Now, you can do spGetCurDateTime()
instead of Test::spGetCurDateTime
, but you haven't overridden log
with out realizing it. You can still say Test::log
to execute the log
subroutine in your Module.
精彩评论