开发者

help calling a sub routine from a perl module and printing to logfile

开发者 https://www.devze.com 2023-03-21 17:19 出处:网络
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'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 ofTest::spGetCurDateTimeandTest::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.

0

精彩评论

暂无评论...
验证码 换一张
取 消