Re: AIX and gcc (moving targets)
[p5sagit/p5-mst-13.2.git] / lib / autouse.pm
CommitLineData
68dc0745 1package autouse;
2
3#use strict; # debugging only
4use 5.003_90; # ->can, for my $var
5
4fd80133 6$autouse::VERSION = '1.02';
68dc0745 7
6363f07a 8$autouse::DEBUG ||= 0;
68dc0745 9
10sub vet_import ($);
11
12sub croak {
13 require Carp;
14 Carp::croak(@_);
15}
16
17sub import {
6363f07a 18 my $class = @_ ? shift : 'autouse';
19 croak "usage: use $class MODULE [,SUBS...]" unless @_;
68dc0745 20 my $module = shift;
21
22 (my $pm = $module) =~ s{::}{/}g;
23 $pm .= '.pm';
24 if (exists $INC{$pm}) {
25 vet_import $module;
26 local $Exporter::ExportLevel = $Exporter::ExportLevel + 1;
27 # $Exporter::Verbose = 1;
4fd80133 28 return $module->import(map { (my $f = $_) =~ s/\(.*?\)$//; $f } @_);
68dc0745 29 }
30
31 # It is not loaded: need to do real work.
32 my $callpkg = caller(0);
6363f07a 33 print "autouse called from $callpkg\n" if $autouse::DEBUG;
68dc0745 34
35 my $index;
36 for my $f (@_) {
37 my $proto;
38 $proto = $1 if (my $func = $f) =~ s/\((.*)\)$//;
39
40 my $closure_import_func = $func; # Full name
41 my $closure_func = $func; # Name inside package
f1c689a8 42 my $index = index($func, '::');
68dc0745 43 if ($index == -1) {
44 $closure_import_func = "${callpkg}::$func";
45 } else {
46 $closure_func = substr $func, $index + 2;
47 croak "autouse into different package attempted"
48 unless substr($func, 0, $index) eq $module;
49 }
50
51 my $load_sub = sub {
fb73857a 52 unless ($INC{$pm}) {
53 eval {require $pm};
54 die if $@;
68dc0745 55 vet_import $module;
56 }
f1c689a8 57 no warnings 'redefine';
68dc0745 58 *$closure_import_func = \&{"${module}::$closure_func"};
59 print "autousing $module; "
60 ."imported $closure_func as $closure_import_func\n"
6363f07a 61 if $autouse::DEBUG;
68dc0745 62 goto &$closure_import_func;
63 };
64
65 if (defined $proto) {
66 *$closure_import_func = eval "sub ($proto) { &\$load_sub }";
67 } else {
68 *$closure_import_func = $load_sub;
69 }
70 }
71}
72
73sub vet_import ($) {
74 my $module = shift;
75 if (my $import = $module->can('import')) {
76 croak "autoused module has unique import() method"
fb73857a 77 unless defined(&Exporter::import)
68dc0745 78 && $import == \&Exporter::import;
79 }
80}
81
821;
83
84__END__
85
86=head1 NAME
87
88autouse - postpone load of modules until a function is used
89
90=head1 SYNOPSIS
91
92 use autouse 'Carp' => qw(carp croak);
93 carp "this carp was predeclared and autoused ";
94
95=head1 DESCRIPTION
96
97If the module C<Module> is already loaded, then the declaration
98
99 use autouse 'Module' => qw(func1 func2($;$) Module::func3);
100
101is equivalent to
102
103 use Module qw(func1 func2);
104
105if C<Module> defines func2() with prototype C<($;$)>, and func1() and
106func3() have no prototypes. (At least if C<Module> uses C<Exporter>'s
107C<import>, otherwise it is a fatal error.)
108
109If the module C<Module> is not loaded yet, then the above declaration
110declares functions func1() and func2() in the current package, and
111declares a function Module::func3(). When these functions are called,
112they load the package C<Module> if needed, and substitute themselves
113with the correct definitions.
114
115=head1 WARNING
116
117Using C<autouse> will move important steps of your program's execution
118from compile time to runtime. This can
119
bbc7dcd2 120=over 4
68dc0745 121
122=item *
123
124Break the execution of your program if the module you C<autouse>d has
125some initialization which it expects to be done early.
126
127=item *
128
129hide bugs in your code since important checks (like correctness of
130prototypes) is moved from compile time to runtime. In particular, if
131the prototype you specified on C<autouse> line is wrong, you will not
132find it out until the corresponding function is executed. This will be
133very unfortunate for functions which are not always called (note that
134for such functions C<autouse>ing gives biggest win, for a workaround
135see below).
136
137=back
138
139To alleviate the second problem (partially) it is advised to write
140your scripts like this:
141
142 use Module;
143 use autouse Module => qw(carp($) croak(&$));
144 carp "this carp was predeclared and autoused ";
145
146The first line ensures that the errors in your argument specification
147are found early. When you ship your application you should comment
148out the first line, since it makes the second one useless.
149
68dc0745 150=head1 AUTHOR
151
152Ilya Zakharevich (ilya@math.ohio-state.edu)
153
154=head1 SEE ALSO
155
156perl(1).
157
158=cut