Reputation: 423
Coming from Python and Java background this is confusing me a bit. I have the following files:
Constants.pm
Utils.pl
Main.pl
Constants.pm has global variables that I'd like to share with Main.pl and Utils.pl.
Utils.pl has helper subs that I'd like to share with Constants.pm and Main.pl
#################### Constants.pm
package Constants;
require "Utils.pl";
use Exporter;
our @ISA = 'Exporter';
my %config = parseConfigFile("File.properties");
our @EXPORT = qw($var1 $var2 $var3);
our ($var1, $var2, $var3);
$var1 = $config{var1};
$var2 = $config{var2};
$var3 = $config{var3};
#################### Utils.pl
package Utils;
use Constants;
sub parseConfigFile {};
sub someSub {};
#################### Main.pl
use Constants;
require "Utils.pl"
my $var = someSub($var1);
When I run Main.pl I'm getting someSub is undefined error
Please help, thanks!
EDIT: I haven't tried @ikegami's answer instead I just moved everything in Constants into Utils.pm and importing Utils by using 'use' in main.pl
Upvotes: 0
Views: 125
Reputation: 386591
[The following explanation applies to the original version of the question. The solution is the same.]
require
only executes a file once, but you expect the identical subs to be present in two packages. The simple solution is to use do
instead of require
. But then you end up with a poor design. You end up with multiple instances of the variables and subs created by Utils.pl
. It's much better to convert Utils.pl
into a proper module (like Constants.pm
).
Constants.pm
:
package Constants;
use strict;
use warnings;
use Exporter qw( import );
use Utils qw( parseConfigFile );
our @EXPORT_OK = qw( $var1 $var2 $var3 );
my %config = parseConfigFile("File.properties");
our $var1 = $config{var1};
our $var2 = $config{var2};
our $var3 = $config{var3};
1;
Utils.pm
:
package Utils;
use strict;
use warnings;
use Constants qw( ... );
use Exporter qw( import );
our @EXPORT_OK = qw( parseConfigFile someSub );
sub parseConfigFile { ... }
sub someSub { ... }
1;
main.pl
:
#!/usr/bin/perl
use strict;
use warnings;
use Constants qw( $var1 );
use Utils qw( someSub );
my $var = someSub($var1);
But oops! Constants uses Utils, and Utils uses Constants, and they both import from the other. That's a problem. You can work around it, but there's no reason for parseConfigFile
to be in Utils
, so let's just avoid the problem entirely.
Constants.pm
:
package Constants;
use strict;
use warnings;
use Exporter qw( import );
our @EXPORT_OK = qw( $var1 $var2 $var3 );
sub parseConfigFile { ... }
my %config = parseConfigFile("File.properties");
our $var1 = $config{var1};
our $var2 = $config{var2};
our $var3 = $config{var3};
1;
Utils.pm
:
package Utils;
use strict;
use warnings;
use Constants qw( ... );
use Exporter qw( import );
our @EXPORT_OK = qw( someSub );
sub someSub { ... }
1;
(I use @EXPORT_OK
instead of @EXPORT
because I believe it's a good idea to explicitly name your imports.)
Upvotes: 1