Understanding `use` in Perl: Modules, Pragmas, Imports, and Compile-Time Behavior
Question
what is use in perl
Difficulty: Beginner (with some intermediate details)
Tags: Perl, use, require, modules, pragmas, import, @INC, strict, warnings, CPAN
What is use in Perl?
In Perl, use is a keyword primarily used to:
- Load a module (a reusable library, typically a
.pmfile) - Enable a pragma (a compiler directive that changes how Perl parses/compiles code, such as
strictorwarnings) - Optionally import symbols into the current package/namespace (functions/constants provided by the module)
- Do the above at compile time (important distinction vs runtime loading)
Key idea: use happens at compile time
The most important concept is that use runs during compilation, not during normal runtime execution. Conceptually, Perl treats:
use Some::Module qw(foo bar);
as roughly equivalent to:
BEGIN {
require Some::Module;
Some::Module->import(qw(foo bar));
}
That BEGIN { ... } block runs immediately as the file is compiled, before your script starts “running” line-by-line. This is why use is excellent for enabling compile-time behaviors (strict, warnings, feature) and for ensuring dependencies are present early.
Common forms of use
Here are the patterns you’ll see most often:
use strict;— enable strict rules (pragma)use warnings;— enable warnings (pragma)use feature 'say';— enable a language feature (pragma-like)use Module;— load a module and import its default exports (if any)use Module ();— load a module but import nothinguse Module qw(func1 func2);— load and import selected symbolsuse Module 1.23 qw(...);— require at least version 1.23 of the moduleuse v5.36;— require a minimum Perl version (and may enable a feature bundle depending on version)
Modules vs pragmas (why you often see use for both)
Modules (e.g., List::Util, Time::Piece) provide reusable functions/classes. They are loaded from disk (or already-loaded module cache) and can export symbols.
Pragmas (e.g., strict, warnings, utf8, feature) alter compiler/interpreter behavior, often lexically (limited to a scope). Many pragmas are implemented as modules under the hood, but they are used to control compilation and interpretation rules rather than to provide application functions.
Runnable example 1: importing functions with use
This example uses a core module (List::Util) and imports just the sum function.
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use List::Util qw(sum);
my @nums = (1, 2, 3, 4, 5);
say sum(@nums);
Expected output:
15
What this shows: use List::Util qw(sum); loads the module and calls its import method to make sum available as an unqualified function in your current package.
Runnable example 2: using a core module class with use
This example loads Time::Piece (commonly available in modern Perls) to parse a date and print the weekday number.
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;
my $t = Time::Piece->strptime('2026-01-01', '%Y-%m-%d');
# wday: 1=Sunday, 2=Monday, ..., 5=Thursday
say $t->wday;
Expected output:
5
What this shows: use Time::Piece; loads the module so the class methods (like strptime) are available. Many OO-style modules don’t rely on exporting functions; you just use the class/package name.
Runnable example 3: proving use runs at compile time
This example creates a fake module in-memory, marks it as “already loaded” in %INC, and then uses it. The key point is that the module’s import runs during compilation, before the runtime print.
#!/usr/bin/env perl
use strict;
use warnings;
BEGIN {
package My::Pragma;
sub import {
print "My::Pragma import at compile time\n";
}
$INC{'My/Pragma.pm'} = 1;
}
use My::Pragma;
print "runtime\n";
Expected output:
My::Pragma import at compile time
runtime
What this shows: use My::Pragma; triggers an implicit BEGIN block that calls import during compilation. Even though the statement appears “before” the print in the file, its effects happen before runtime begins.
use vs require (real-world decision)
require is the runtime cousin of use. Key differences:
- Timing:
useis compile-time;requireis runtime. - Importing:
usecallsimportautomatically;requiredoes not. If you want imports afterrequire, you must call->importyourself. - Dynamic loading: plugin systems and optional dependencies usually use
require(often insideeval) so the program can continue if the module isn’t installed.
Typical plugin-style pattern:
eval {
require Some::Optional;
Some::Optional->import('optional_func');
1;
} or do {
warn "Optional module not available: $@";
};
This is hard to do cleanly with use because use happens too early (during compile time) and failures generally stop compilation.
How imports work (and how to avoid namespace mess)
Many modules export functions. That can be convenient, but it can also create name collisions (two modules export sum, any, first, etc.). Best practices include:
- Import only what you need:
use List::Util qw(sum); - Import nothing and call fully qualified:
use List::Util ();thenList::Util::sum(@nums) - Be careful with default exports: some modules export many names by default; prefer explicit import lists.
Best practices for production Perl
- Always start scripts with:
use strict;anduse warnings;(and oftenuse feature 'say';or a modern version declaration). - Pin minimum versions when it matters:
use Some::Module 2.14;so you don’t silently run against older behavior. - Prefer lexical pragmas and scoped disabling: if you must relax rules, do it narrowly (e.g.,
no strict 'refs';only in a tiny scope). - Avoid global
@INChacks: prefer well-defined library paths (packaging,local::lib, containers) over sprinkling ad-hocuse libin many files. - Use
use libintentionally: it changes where Perl searches for modules. This is often used in apps to include a projectlib/directory, but be mindful of relative paths and deployment layout. - Be explicit about encoding:
use utf8;affects how your source code is read; it does not automatically decode input data. Treat source encoding and I/O encoding as separate concerns.
Common pitfalls and gotchas
- Thinking
useis runtime: it’s compile-time. If you writeif ($cond) { use X; }, it won’t behave the way you expect because theuseis processed before runtime conditionals. Userequirefor conditional/dynamic loading. - Forgetting that
requiredoesn’t import: afterrequire Module;, you don’t automatically get exported functions unless you callModule->import(...). - Importing too much:
use Some::BigModule;might pull many symbols into your namespace; collisions can create confusing bugs. Prefer explicit import lists. - Misunderstanding
use utf8;: it only affects the Perl parser reading your source. It does not decode files you read from disk or sockets. - Module search path issues: “Can’t locate Foo/Bar.pm in @INC” usually means the module isn’t installed where Perl can find it, or your app’s
libpath isn’t configured correctly. - Version declarations:
use v5.x;enforces a minimum Perl version; depending on the version, it may enable feature bundles. Be deliberate and test on your deployment Perl.
Real-world usage patterns
- Scripts and cron jobs: almost always start with
use strict; use warnings;, then load a handful of core/CPAN modules withuse. - Web apps / APIs: use loads frameworks and middleware early; explicit imports keep namespaces clean and predictable.
- Libraries: modules use
use strict/warningsinternally, and often useExporter(or modern alternatives) to control what callers can import. - Feature gating:
use feature ...or version declarations help keep code readable and consistent with the Perl features you rely on. - Plugin systems: typically avoid
usefor plugins; they userequireso plugins can be discovered/loaded dynamically and failures handled gracefully.
Summary
use in Perl is the standard way to load modules and enable pragmas at compile time, optionally importing symbols into your namespace. Understanding its compile-time nature, how it differs from require, and how imports affect namespaces will help you write safer, clearer, and more maintainable Perl—especially in production codebases.
Verified Code
Executed in a sandbox to capture real output. • 6ms
My::Pragma import at compile time
runtime
(empty)