Reputation: 1773
My end goal is to use an argument as the package. I can't get a simple example to work though. Is there a way to use
a $variable
as my package?
MyModule.pm
package MyModule;
use strict;
use warnings;
use parent 'Exporter'; # imports and subclasses Exporter
our $test="hello world\n";
our @EXPORT = qw($test);
program.pl
#!/usr/bin/perl
use strict;
use warnings;
my $x = 'MyModule.pm';
eval "require $x";
MyModule->import;
print "$test\n";
Error
Global symbol "$test" requires explicit package name at ./program.pl line 8.
Execution of ./program.pl aborted due to compilation errors.
Upvotes: 0
Views: 778
Reputation: 98398
require has two syntaxes; one expects an unquoted package name (e.g. require Foo::Bar;
), the other expects an expression that yields a filename (e.g. require "Foo/Bar.pm";
). Note that the latter still searches the library directories, and works with /
between components even on systems that use other path separators.
Your:
my $x = 'MyModule.pm';
eval "require $x";
trying to eval the code require MyModule.pm
is mixing up the two forms and gives an error Bareword "pm" not allowed while "strict subs" in use
(which is caught by the eval and placed in $@).
So either just do my $x = 'MyModule';
(and check if eval caught an error, for robustness) or just do:
my $x = 'MyModule.pm';
require $x;
(or eval { require $x }
if you wish to trap errors).
That still leaves you your strict error on $test
because $test
is not exported until runtime and the strict check is at compile time; to solve that, you need to be able to perform your require at compile time:
#!/usr/bin/perl
use 5.014;
use warnings;
BEGIN {
my $x = 'MyModule';
my $filename = "$x.pm" =~ s!::!/!gr;
require $filename;
$x->import;
}
say $test;
Upvotes: 1