using multiple "use Module" statements

D

dszostek

Hi,

If I have "use Module;" in a subroutine that may be called more than
once, does it re-load anything from the module? Is there any
performance issue with doing this or does it just ignore the statement
if the module has already been loaded.

Thanks,
Dave
 
S

Sherm Pendley

If I have "use Module;" in a subroutine that may be called more than
once, does it re-load anything from the module?

It's only loaded once, for two reasons:

First, "use Module" is executed at *compile* time, and the subroutine is
compiled only once no matter how many times you call it at run time.

And second, when a module is included via do, use, or require, Perl checks
first for an entry for that module in %INC. If an entry is found, nothing
happens. If none is found, the module is loaded and an entry is created.

Have a look at:

perldoc -f use
perldoc -f do
perldoc -f require
perldoc perlvar # Look for %INC

sherm--
 
B

Bob Walton

If I have "use Module;" in a subroutine that may be called more than
once, does it re-load anything from the module? Is there any
performance issue with doing this or does it just ignore the statement
if the module has already been loaded. ....
Dave
Per
perldoc -f use
one sees that require() is the underlying implementation of
use(). Then from
perldoc -f require
one sees that require() "demands that a library file be included
if it hasn't already been included.". So the module is loaded
only once. %INC keeps track of this. Note that the module's
->import() method will be called for each use() call even if the
module has already been loaded.
 
S

Sherm Pendley

Bob Walton said:
Per
perldoc -f use
one sees that require() is the underlying implementation of use().

One also sees that use() is executed at compile time.
%INC keeps track of this. Note that the module's ->import() method
will be called for each use() call even if the module has already been
loaded.

That will still only be once, because a subroutine is compiled only once
no matter how many times it might be called. That includes zero times -
a subroutine that's never called is still compiled.

sherm--
 
B

Bob Walton

Sherm said:
That will still only be once, because a subroutine is compiled only once
no matter how many times it might be called. That includes zero times -
a subroutine that's never called is still compiled.

Counterexample:

#File junk552.pm:
package junk552;
sub import{
print "import called:mad:_\n";
}
1;

#File junk552.pl:
use junk552(a);
use junk552(b);

#Results of run:
d:\junk>perl junk552.pl
import called:junk552 a
import called:junk552 b

d:\junk>
 
S

Sherm Pendley

Bob Walton said:
Counterexample:

#File junk552.pm:
package junk552;
sub import{
print "import called:mad:_\n";
}
1;

#File junk552.pl:
use junk552(a);
use junk552(b);

#Results of run:
d:\junk>perl junk552.pl
import called:junk552 a
import called:junk552 b

I thought I'd left enough quotage to make the context clear, but I may have
oversnipped - sorry 'bout that.

Anyhow, we were discussing a single use() statement appearing in a subroutine
that's called many times. For instance:

sub foo {
use junk552(a);
}

The "use junk552(a);" is evaluated at compile-time, so it's called only once
no matter how many times you call foo() at run-time.

Your counter example doesn't negate that point, it simply illustrates something
entirely different - although a given module is only loaded and compiled once,
its import() subroutine may be called any number of times. If you really think
about it, it's obvious why this happens - how else could a package's symbols be
exported into more than one name space?

But as your example shows, that happens as a result of multiple use() state-
ments. It would not happen as a result of additional invocations of foo() in
the example above.

If you want to have a use() that's evaluated at run-time, you have to wrap it
in a string eval().

sub foo {
eval 'use junk552(a)';
}

One common use of this is to make the use of a module optional by checking for
its existence at run-time:

our $junk_exists;

sub check_junk {
$junk_exists = eval 'use junk552';
}

# ...later...

if ($junk_exists) {
my $foo = new junk552();
}

sherm--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top