I have a shared module in perl. The main program needs two files, first, a 开发者_C百科shared file (let's call it 'X'), and, second, a 'package' file. File 'X' is also included in the 'package' file using 'require'. When I compile this program it gives me the following error:
Undefined subroutine &main::trim called at testing.pl line 8.
My understanding is that perl couldn't find the trim() module. If I don't include the package file, then this will run without any problem.
Can anyone shed light on this problem?
These are my codes:
Main program: testing.pl
#!/usr/bin/perl -w
use strict;
use postgres;
require "shared.pl";
trim("als");
Package File: postgres.pm
#!/usr/bin/perl
package postgres;
use strict;
use DBI;
require "shared.pl";
1;
shared file: shared.pl
#!/usr/bin/perl
# =============
# shared module
# =============
use strict;
sub trim($)
{
}
1;
If the module doesn't use package
, you want do
instead of require
. See What is the difference between library files and modules?.
do "shared.pl" or die $@;
You really should create a proper module, one with a package
statement.
package Shared;
use strict;
use warnings;
our @EXPORT = qw( trim );
use Exporter qw( import );
sub trim { ... }
1;
Name the file Shared.pm
and load it using use Shared;
.
By default, require
will only load a file one time. In this case, that one time is from the file postgres.pm
, in the postgres
package. So the trim
subroutine gets defined in the postgres
namespace as &postgres::trim
.
One workaround would be to use the fully qualified subroutine name in the testing.pl
file:
postgres::trim("als"); # not trim("als")
Another workaround is to hack the %INC
table (the variable that keeps track of what modules/files have already been use
'd and require
'd) so you can reload shared.pl
into the main package:
use postgres;
delete $INC{"shared.pl"};
require "shared.pl";
A third workaround would be to export the trim
function from the postgres
package to the main package. The docs for the Exporter
module are a good introduction to why and how this is done.
# in postgres.pm
*main::trim = *trim;
# or in testing.pl
*trim = *postgres::trim;
trim("als");
精彩评论