Imagine I want to load a module at runtime. I expected this to work
use warnings;
use strict;
eval {
require Cwd;
Cwd->import;
};
if ($@) { die "Can't load Cwd: $@" }
say "Dir: ", getcwd;
but it doesn't, per Bareword "getcwd" not allowed ...
.
The Cwd exports getcwd
by default. I tried giving the function name(s) to import
and I tried with its other functions.
It works with the full name, say Cwd::getcwd
, so I'd think that it isn't importing.
This works as attempted for a few other core modules that I tried, for example
use warnings;
use strict;
eval {
require List::Util;
List::Util->import('max');
};
if ($@) { die "Can't load List::Util: $@" }
my $max = max (1, 14, 3, 26, 2);
print "Max is $max\n";
NOTE added Apparently, function calls with parenthesis give a clue to the compiler. However, in my opinion the question remains, please see EDIT at the end. In addition, a function like first BLOCK LIST
from the module above does not work.
However, it does not work for a few (well established) non-core modules that I tried. Worse and more confusingly, it does not work even with the fully qualified names.
I can imagine that the symbol (function) used is not known at compile time if require
is used at runtime, but it works for (other) core modules. I thought that this was a standard way to load at runtime.
If I need to use full names when loading dynamically then fine, but what is it with the inconsistency? And how do I load (and use) non-core modules at runtime?
I also tried with Module::Load::Conditional
and it did not work.
What am I missing, and how does one load modules at runtime? (Tried with 5.16
and 5.10.1
.)
EDIT
As noted by Matt Jacob, a call with parenthesis works, getcwd()
. However, given perlsub
NAME LIST;
# Parentheses optional if predeclared/imported.
this implies that the import didn't work and the question of why remains.
Besides, having to use varied syntax based on how the module is loaded is not good. Also, I cannot get non-core modules to work this way, specially the ones with syntax like List::MoreUtils has.
First, this has nothing to do with core vs. non-core modules. It happens when the parser has to guess whether a particular token is a function call.
At compile time, there is no
getcwd
in themain::
symbol table. Without any hints to indicate that it's a function (getcwd()
or&getcwd
), the parser has no way to know, andstrict
complains.At compile time, there is no
max
in themain::
symbol table. However, since you callmax
with parentheses, the parser can guess that it's a function that will be defined later, sostrict
doesn't complain.In both cases, the
strict
check happens beforeimport
is ever called.List::MoreUtils is special because the functions use prototypes. Prototypes are ignored if the function definition is not visible at compile time. So, not only do you have to give the parser a hint that you're calling a function, you also have to call it differently since the prototype will be ignored: