开发者

Perl problem 'require' the same file

开发者 https://www.devze.com 2023-03-22 02:39 出处:网络
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

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");
0

精彩评论

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