NAME
later - A pragma to postpone using a module
SYNOPSIS
Assuming we have a module Foo exporting the function bar():
package Foo;
use base qw(Exporter);
our @EXPORT_OK = qw(bar);
sub bar {
# do whatever
}
1;
And somewhere else we use Foo and call bar():
use Foo qw(bar);
bar('some','arguments');
Now, for a number of possibly rather unsane reasons you might want to delay actually evaling 'use Foo' until bar
is called at runtime. To do that, change the former code into:
use later 'Foo', qw(bar);
bar('some','arguments');
This works even for object packages:
use later 'My::Classy::Class';
my $object = new My::Classy::Class;
And supports import arguments:
use later 'My::Classy::Class', do_fuss => 1;
my $object = new My::Classy::Class;
DESCRIPTION
The later
pragma enables you to postpone using a module until its exported methods are needed during runtime.
API
use later 'Module::Name';
-
or
use later 'Module::Name', arg1 => $value1, ...;
-
Postpones
use Module::Name
until an undefined subroutine is found in the current package at runtime. Only when it happens shalllater
evaluate c<use Module::Name> inside the current package, hence hopefully importing the undefined subroutine into the current package's namespace. The formerly undefined subroutine is then called as if nothing unusual had happened.Any further encounter with an undefined subroutine will still result in the standard 'Undefined subroutine' error.
If multiple modules are called with
use later
inside the same package, they will all be used upon the first encounter with an undefined subroutine in this package, despite the fact that only one of them should export the specific undefined subroutine.If
Module::Name
is called with import arguments, those will be passed to the module when it is used. Note that thelater
pragma does not support passing code refs as import arguments.You may
use later
modules thatuse later
other modules (and so on recursively). It works.Examples:
use later 'Data::Dumper'; # Data::Dumper is effectively used upon calling 'Dumper' print Dumper([1,2,3]);
or
use later 'MyLog', level => 1; # MyLog is used with the import parameters 'level => 1' upon calling 'mylog' mylog("some message");
Notice that when passing import arguments together with the module name, you have to separate them from the module name with a comma ','.
Notice too that function names coming from modules that are used later must end with parenthesis in order for your code to compile (ex:
foo()
instead offoo
).
BUGS AND LIMITATIONS
This module is a proof of concept.
The later
pragma will not work properly if the calling module or the postponed module has an AUTOLOAD function, since it will conflict with the AUTOLOAD that later
silently injects into them.
The later
pragma does not support passing code references as import arguments to the postponed module.
Since postponed modules are searched for and compiled only during runtime, any error in the module (compilation or other) is delayed until then. You are therefore at risk of crashing your program in the middle of its runtime due to errors that would normally be detected during compilation.
As far as I am concerned, I fail to see any sane situation where this pragma would be needed that cannot be implemented in a safer way without later
. You have been warned :)
Should you find bugs or suggest changes, please send an email to <erwan@cpan.org>
.
SEE ALSO
See 'load', 'SelfLoader', 'AutoLoader'.
VERSION
$Id: later.pm,v 1.7 2007/01/23 16:05:12 erwan Exp $
AUTHOR
Erwan Lemonnier <erwan@cpan.org>
COPYRIGHT AND LICENSE
This code is distributed under the same terms as Perl itself.
DISCLAIMER OF WARRANTY
This is free code and comes with no warranty. The author declines any personal responsibility regarding the use of this code or the consequences of its use.