Background:
Perl has supported dynamic and static code loading since it introduced module support. The language provides three different mechanisms for this: require, use, and do. Each has its own features, different execution lifecycles, and impacts on the program's working context.
Problem:
Incorrect choice of loading mechanism or misunderstanding of their differences often leads to bugs: reloading modules, scope issues, runtime errors (e.g., failed loads, uninitialized variables or functions).
Solution:
use — loads a module at compile time. Automatically calls the import method if defined. Used for loading modules and declarations at the program's start.require — loads a file or module at runtime, only once per program. Well-suited for dynamically loading files conditionally.do — simply executes a file as Perl code every time it is called. Rarely used, needed for special cases (e.g., configuration files).Example code:
use Some::Module; # static loading if ($config{plugin}) { require "$config{plugin}.pm"; # dynamic loading } do 'local_config.pl'; # executes every time upon invocation
Key features:
use only works with packages/modules, calls import, triggers at compilation.require works with files and modules, executes at runtime.do does not cache the module but simply executes the file's content.Can require be used to associate with a variable and a module like Some::Module?
Yes, but the path to the file must be specified explicitly, or the module name must be transformed into a path:
my $mod = 'Some::Module'; $mod =~ s!::!/!g; require "$mod.pm"; # correct
What happens if do cannot find the file?
do returns false (undef) and records an error in $@ — it does not panic like use/require.
What happens if require is called twice on the same file?
require loads the file only the first time; subsequent calls will not repeat the loading, even if the original file has changed.
In a project, attempts were made to dynamically load plugins using do, not checking the return status and confused it with require.
Pros:
Cons:
Used require for conditional loading, always transformed the module name into a path. Checked $@ after attempt to load.
Pros:
Cons: