Perl Part I · Module 12 · Modules and Packages
use vs require: Compile Time vs Run Time
Both keywords load a module from another file, and almost everything you will read tells you to use the first one and leave the second alone. That advice is right, and following it without understanding the difference leaves you unable to read the error you will eventually get, or to write the one case where require is the correct choice. The difference is when the loading happens. use runs while Perl is still compiling your file, before any of your statements have executed; require runs at the moment control reaches that line, like an ordinary statement. Section two measures that in the starkest form available: two scripts identical but for the keyword, both failing on a module that does not exist, where one prints its first line and the other prints nothing whatsoever. The second difference is what each one brings with it — use imports names into your package and require imports nothing — and the chapter closes on the case that justifies require's existence, a module your script can work without.
Intermediate12 min readPerlPart IModules
Part I · Module 12 · Chapter 12.3 · use vs require: Compile Time vs Run Time
1. When Each One Happens
A BEGIN block runs at compile time, in source order, which makes it the right probe for this question.
use strict;
use warnings;
# A BEGIN block runs at COMPILE time, so it shows us the ordering.
BEGIN { print "1. compile time: before the use line is reached\n" }
use lib 'lib';
use VLSI::Units;
BEGIN { print "2. compile time: after the use line\n" }
print "3. run time: the body of the script starts here\n";
require VLSI::Log;
print "4. run time: require happened just now\n";
printf "both loaded : %s %s\n",
(exists $INC{"VLSI/Units.pm"} ? "Units" : "-"),
(exists $INC{"VLSI/Log.pm"} ? "Log" : "-");1. compile time: before the use line is reached
2. compile time: after the use line
3. run time: the body of the script starts here
4. run time: require happened just now
both loaded : Units LogRead the numbers in the order they printed. Both BEGIN blocks ran before the first ordinary print statement, because compilation of the whole file finishes before execution of any of it begins. The use sits between them, so it had already happened by the time line 3 ran.
The require is different: it printed between lines 3 and 4, in sequence with the ordinary statements, because it is an ordinary statement.
Both modules ended up loaded, which the last line confirms by looking in %INC — the hash Chapter 12.4 covers. The destination is the same; the timing is not.
2. What That Costs When the Module Is Missing
This is the measurement that makes the distinction concrete rather than academic.
use strict;
use warnings;
use File::Temp qw(tempdir);
use File::Spec;
my $dir = tempdir(CLEANUP => 1);
# Two child scripts, identical except for use vs require.
my %src = (
"with-use.pl" => qq{print "A: before\\n";\nuse Totally::Missing;\nprint "B: after\\n";\n},
"with-require.pl" => qq{print "A: before\\n";\nrequire Totally::Missing;\nprint "B: after\\n";\n},
);
for my $name (sort keys %src) {
my $path = File::Spec->catfile($dir, $name);
open my $fh, ">", $path or die $!;
print $fh $src{$name};
close $fh;
my $out = `perl "$path" 2>/dev/null`;
my $rc = $? >> 8;
$out =~ s/\s+\z//;
$out =~ s/\n/ | /g;
printf "%-16s exit %d stdout: %s\n", $name, $rc, ($out eq "" ? "(nothing)" : $out);
}
print "\nuse fails while the file is being COMPILED, so not even line 1 runs\n";
print "require fails when that LINE runs, so line 1 had already printed\n";with-require.pl exit 2 stdout: A: before
with-use.pl exit 2 stdout: (nothing)
use fails while the file is being COMPILED, so not even line 1 runs
require fails when that LINE runs, so line 1 had already printedTwo scripts differing by one keyword. Both exit 2. One printed its first line; the other printed nothing at all.
The use version never got as far as executing anything. Perl read the file, reached the use, could not find the module, and abandoned compilation — so line 1, which was perfectly valid and had nothing to do with the module, never ran.
That is the behaviour you want for a dependency your script genuinely needs. Failing before doing any work is strictly better than failing halfway through: nothing has been written, no partial report exists, and the failure is unambiguous. It is the same argument as use strict catching a typo at compile time rather than at the moment the bad line happens to execute.
The require version did half the job before failing. On a script that writes files, that is a partially written output and a cleanup problem.
The technique in that script is worth noting on its own: the parent writes two child scripts to a temporary directory and runs each with backticks, capturing stdout and the exit status. That is how you measure a compile-time failure from inside a running program — you cannot do it in one file, because a use of a missing module in the file you are running would stop that file.
3. use Imports Names; require Does Not
use strict;
use warnings;
use lib 'lib';
# use ... qw(...) calls import(), which installs the names in THIS package.
use VLSI::Log qw(parse_slack);
my $r = parse_slack("u_alu/A -0.12"); # unqualified: import gave us the name
printf "via import : %s\n", $r->{pin};
# require loads the file and installs NOTHING.
require VLSI::Units;
printf "require + full : %s\n", VLSI::Units::to_ns(420, "ps");
# the unqualified name is NOT available after require
my $ok = eval { to_ns(1, "ns"); 1 };
printf "unqualified after require : %s\n", ($ok ? "worked" : "failed as expected");via import : u_alu/A
require + full : 0.42
unqualified after require : failed as expectedAfter use VLSI::Log qw(parse_slack), the bare name parse_slack works in this file — the module's import put it there. Chapter 12.6 is about how a module decides what it will hand over.
After require VLSI::Units, the module is loaded and usable, but only by its full name. VLSI::Units::to_ns(...) works; the bare to_ns(...) does not, and the last line confirms it fails.
This is a feature rather than a limitation. A require that imported names would be modifying your namespace at an unpredictable moment during execution, which is exactly the kind of action-at-a-distance that makes code hard to reason about. If you want the names, you want use.
4. The Run-Time Failure, and What It Says
use strict;
use warnings;
print "this line runs\n";
# require of a missing module fails at RUN time, so the print above happened.
my $ok = eval { require VLSI::Missing; 1 };
if (!$ok) {
my ($first) = split /\n/, $@;
$first =~ s/ \(\@INC contains:.*//; # drop the machine-specific path list
printf "require failed at run time: %s\n", $first;
}
print "and the script continues\n";this line runs
require failed at run time: Can't locate VLSI/Missing.pm in @INC (you may need to install the VLSI::Missing module)
and the script continuesBecause require is an ordinary statement, it can be wrapped in eval and the failure caught — which is the whole basis of the next section. The script carried on and printed its last line.
Two details about the error itself. The module name VLSI::Missing became the path VLSI/Missing.pm, which is the translation Chapter 12.4 explains. And the real message continues with a parenthesised list of every directory Perl searched; the script strips that clause, because it is a list of absolute paths specific to one machine and would make this page's output impossible to reproduce elsewhere.
A use cannot be caught this way, because the failure happens during compilation of the enclosing file — there is no running eval yet. If you need to catch it, the form is eval { require Module; 1 }, which is what the next section uses.
5. The Case That Justifies require
use strict;
use warnings;
# The real use for require: a module you may not need.
my $have_json = eval { require JSON::PP; 1 } ? 1 : 0;
my $have_fake = eval { require Totally::Not::Installed; 1 } ? 1 : 0;
printf "JSON::PP available : %s\n", ($have_json ? "yes" : "no");
printf "Totally::Not::Installed : %s\n", ($have_fake ? "yes" : "no");
printf "report format : %s\n", ($have_json ? "json" : "plain text");JSON::PP available : yes
Totally::Not::Installed : no
report format : jsonThis is the pattern the canonical description points at: a module you may not need. The script asks whether JSON::PP is installed, gets yes on this machine, and chooses its output format accordingly. Asked about a module that does not exist, it gets no, and carries on.
Written with use, this script would simply refuse to start on a machine without the module — even for a run that was never going to want JSON output.
Two other legitimate uses, both consequences of the same timing:
A module that is expensive and rarely needed. If one branch of a long script needs a heavy module, require inside that branch avoids paying for it on every run.
A module chosen at run time. If the module name comes from configuration, use cannot help you — it needs the name at compile time. require $name does not work either, as require with a plain string expects a filename; the usual form is eval "require $name; 1", which is one of the few places a string eval is the right tool. Treat the name as untrusted input if it came from a file.
6. What To Remember
use Module;isBEGIN { require Module; Module->import(); }. Everything else here follows from that.usehappens at compile time, before any of your statements run.requirehappens when that line is reached.- A missing module under
usemeans nothing runs at all. Measured: theuseversion of a two-print script produced no output; therequireversion printed its first line. Both exited 2. - Failing before doing any work is the behaviour you want for a dependency you actually need — no partial output, no cleanup.
useimports names;requireimports nothing. Afterrequire, only the fully-qualified name works.requirecan be caught witheval;usecannot, because there is no runningevalduring compilation.eval { require Module; 1 }is the idiom for an optional dependency, and lets a script degrade instead of refusing to start.- Also reach for
requirewhen a module is expensive and rarely needed, or when its name is only known at run time (eval "require $name; 1"). - Otherwise use
use. Arequireat the top of a file is almost always a mistake.
Chapter 12.4 answers the question both failure messages raised: where exactly was Perl looking? @INC is the search path, the error prints it in full, and the chapter covers the three correct ways to add your project's own library to it.
Where this fits
Part of the Perl curriculum.
