Cross Reference: autouse.pm
xref
: /
osnet-11
/
usr
/
src
/
cmd
/
perl
/
5.8.4
/
distrib
/
lib
/
autouse.pm
Home
History
Annotate
Line#
Navigate
Download
Search
only in
./
1
N/A
package
autouse
;
1
N/A
1
N/A
#use strict; # debugging only
1
N/A
use
5.003
_90
;
# ->can, for my $var
1
N/A
1
N/A
$
autouse
::
VERSION
=
'1.03'
;
1
N/A
1
N/A
$
autouse
::
DEBUG
||=
0
;
1
N/A
1
N/A
sub
vet_import
($);
1
N/A
1
N/A
sub
croak
{
1
N/A
require
Carp
;
1
N/A
Carp
::
croak
(@_);
1
N/A
}
1
N/A
1
N/A
sub
import
{
1
N/A
my
$
class
= @_ ?
shift
:
'autouse'
;
1
N/A
croak
"usage: use $class MODULE [,SUBS...]"
unless
@_;
1
N/A
my
$
module
=
shift
;
1
N/A
1
N/A
(
my
$
pm
= $
module
) =~ s{::}{/}g;
1
N/A
$
pm
.=
'.pm'
;
1
N/A
if
(
exists
$
INC
{$
pm
}) {
1
N/A
vet_import
$
module
;
1
N/A
local
$
Exporter
::
ExportLevel
= $
Exporter
::
ExportLevel
+
1
;
1
N/A
# $Exporter::Verbose = 1;
1
N/A
return
$
module
->
import
(
map
{ (
my
$f = $_) =~ s/\(.*?\)$//; $f } @_);
1
N/A
}
1
N/A
1
N/A
# It is not loaded: need to do real work.
1
N/A
my
$
callpkg
=
caller
(
0
);
1
N/A
print
"autouse called from $callpkg\n"
if
$
autouse
::
DEBUG
;
1
N/A
1
N/A
my
$
index
;
1
N/A
for
my
$f (@_) {
1
N/A
my
$
proto
;
1
N/A
$
proto
= $
1
if
(
my
$
func
= $f) =~ s/\((.*)\)$//;
1
N/A
1
N/A
my
$
closure_import_func
= $
func
;
# Full name
1
N/A
my
$
closure_func
= $
func
;
# Name inside package
1
N/A
my
$
index
=
rindex
($
func
,
'::'
);
1
N/A
if
($
index
== -
1
) {
1
N/A
$
closure_import_func
=
"${callpkg}::$func"
;
1
N/A
}
else
{
1
N/A
$
closure_func
=
substr
$
func
, $
index
+
2
;
1
N/A
croak
"autouse into different package attempted"
1
N/A
unless
substr
($
func
,
0
, $
index
)
eq
$
module
;
1
N/A
}
1
N/A
1
N/A
my
$
load_sub
=
sub
{
1
N/A
unless
($
INC
{$
pm
}) {
1
N/A
eval
{
require
$
pm
};
1
N/A
die
if
$@;
1
N/A
vet_import
$
module
;
1
N/A
}
1
N/A
no
warnings
'redefine'
;
1
N/A
*$
closure_import_func
= \&{
"${module}::$closure_func"
};
1
N/A
print
"autousing $module; "
1
N/A
.
"imported $closure_func as $closure_import_func\n"
1
N/A
if
$
autouse
::
DEBUG
;
1
N/A
goto
&$
closure_import_func
;
1
N/A
};
1
N/A
1
N/A
if
(
defined
$
proto
) {
1
N/A
*$
closure_import_func
=
eval
"sub ($proto) { &\$load_sub }"
;
1
N/A
}
else
{
1
N/A
*$
closure_import_func
= $
load_sub
;
1
N/A
}
1
N/A
}
1
N/A
}
1
N/A
1
N/A
sub
vet_import
($) {
1
N/A
my
$
module
=
shift
;
1
N/A
if
(
my
$
import
= $
module
->
can
(
'import'
)) {
1
N/A
croak
"autoused module has unique import() method"
1
N/A
unless
defined
(&
Exporter
::
import
)
1
N/A
&& $
import
== \&
Exporter
::
import
;
1
N/A
}
1
N/A
}
1
N/A
1
N/A
1
;
1
N/A
1
N/A
__END__
1
N/A
1
N/A
=head1 NAME
1
N/A
1
N/A
autouse - postpone load of modules until a function is used
1
N/A
1
N/A
=head1 SYNOPSIS
1
N/A
1
N/A
use autouse 'Carp' => qw(carp croak);
1
N/A
carp "this carp was predeclared and autoused ";
1
N/A
1
N/A
=head1 DESCRIPTION
1
N/A
1
N/A
If the module C<Module> is already loaded, then the declaration
1
N/A
1
N/A
use autouse 'Module' => qw(func1 func2($;$));
1
N/A
1
N/A
is equivalent to
1
N/A
1
N/A
use Module qw(func1 func2);
1
N/A
1
N/A
if C<Module> defines func2() with prototype C<($;$)>, and func1() has
1
N/A
no prototypes. (At least if C<Module> uses C<Exporter>'s C<import>,
1
N/A
otherwise it is a fatal error.)
1
N/A
1
N/A
If the module C<Module> is not loaded yet, then the above declaration
1
N/A
declares functions func1() and func2() in the current package. When
1
N/A
these functions are called, they load the package C<Module> if needed,
1
N/A
and substitute themselves with the correct definitions.
1
N/A
1
N/A
=begin _deprecated
1
N/A
1
N/A
use Module qw(Module::func3);
1
N/A
1
N/A
will work and is the equivalent to:
1
N/A
1
N/A
use Module qw(func3);
1
N/A
1
N/A
It is not a very useful feature and has been deprecated.
1
N/A
1
N/A
=end _deprecated
1
N/A
1
N/A
1
N/A
=head1 WARNING
1
N/A
1
N/A
Using C<autouse> will move important steps of your program's execution
1
N/A
from compile time to runtime. This can
1
N/A
1
N/A
=over 4
1
N/A
1
N/A
=item *
1
N/A
1
N/A
Break the execution of your program if the module you C<autouse>d has
1
N/A
some initialization which it expects to be done early.
1
N/A
1
N/A
=item *
1
N/A
1
N/A
hide bugs in your code since important checks (like correctness of
1
N/A
prototypes) is moved from compile time to runtime. In particular, if
1
N/A
the prototype you specified on C<autouse> line is wrong, you will not
1
N/A
find it out until the corresponding function is executed. This will be
1
N/A
very unfortunate for functions which are not always called (note that
1
N/A
for such functions C<autouse>ing gives biggest win, for a workaround
1
N/A
see below).
1
N/A
1
N/A
=back
1
N/A
1
N/A
To alleviate the second problem (partially) it is advised to write
1
N/A
your scripts like this:
1
N/A
1
N/A
use Module;
1
N/A
use autouse Module => qw(carp($) croak(&$));
1
N/A
carp "this carp was predeclared and autoused ";
1
N/A
1
N/A
The first line ensures that the errors in your argument specification
1
N/A
are found early. When you ship your application you should comment
1
N/A
out the first line, since it makes the second one useless.
1
N/A
1
N/A
=head1 AUTHOR
1
N/A
1
N/A
Ilya Zakharevich (ilya@math.ohio-state.edu)
1
N/A
1
N/A
=head1 SEE ALSO
1
N/A
1
N/A
perl(1).
1
N/A
1
N/A
=cut