1898184e3Ssthenpackage autouse;
2898184e3Ssthen
3898184e3Ssthen#use strict;		# debugging only
4898184e3Ssthenuse 5.006;		# use warnings
5898184e3Ssthen
6*b8851fccSafresh1$autouse::VERSION = '1.11';
7898184e3Ssthen
8898184e3Ssthen$autouse::DEBUG ||= 0;
9898184e3Ssthen
10898184e3Ssthensub vet_import ($);
11898184e3Ssthen
12898184e3Ssthensub croak {
13898184e3Ssthen    require Carp;
14898184e3Ssthen    Carp::croak(@_);
15898184e3Ssthen}
16898184e3Ssthen
17898184e3Ssthensub import {
18898184e3Ssthen    my $class = @_ ? shift : 'autouse';
19898184e3Ssthen    croak "usage: use $class MODULE [,SUBS...]" unless @_;
20898184e3Ssthen    my $module = shift;
21898184e3Ssthen
22898184e3Ssthen    (my $pm = $module) =~ s{::}{/}g;
23898184e3Ssthen    $pm .= '.pm';
24898184e3Ssthen    if (exists $INC{$pm}) {
25898184e3Ssthen	vet_import $module;
26898184e3Ssthen	local $Exporter::ExportLevel = $Exporter::ExportLevel + 1;
27898184e3Ssthen	# $Exporter::Verbose = 1;
28898184e3Ssthen	return $module->import(map { (my $f = $_) =~ s/\(.*?\)$//; $f } @_);
29898184e3Ssthen    }
30898184e3Ssthen
31898184e3Ssthen    # It is not loaded: need to do real work.
32898184e3Ssthen    my $callpkg = caller(0);
33898184e3Ssthen    print "autouse called from $callpkg\n" if $autouse::DEBUG;
34898184e3Ssthen
35898184e3Ssthen    my $index;
36898184e3Ssthen    for my $f (@_) {
37898184e3Ssthen	my $proto;
38898184e3Ssthen	$proto = $1 if (my $func = $f) =~ s/\((.*)\)$//;
39898184e3Ssthen
40898184e3Ssthen	my $closure_import_func = $func;	# Full name
41898184e3Ssthen	my $closure_func = $func;		# Name inside package
42898184e3Ssthen	my $index = rindex($func, '::');
43898184e3Ssthen	if ($index == -1) {
44898184e3Ssthen	    $closure_import_func = "${callpkg}::$func";
45898184e3Ssthen	} else {
46898184e3Ssthen	    $closure_func = substr $func, $index + 2;
47898184e3Ssthen	    croak "autouse into different package attempted"
48898184e3Ssthen		unless substr($func, 0, $index) eq $module;
49898184e3Ssthen	}
50898184e3Ssthen
51898184e3Ssthen	my $load_sub = sub {
52898184e3Ssthen	    unless ($INC{$pm}) {
53898184e3Ssthen		require $pm;
54898184e3Ssthen		vet_import $module;
55898184e3Ssthen	    }
56898184e3Ssthen            no warnings qw(redefine prototype);
57898184e3Ssthen	    *$closure_import_func = \&{"${module}::$closure_func"};
58898184e3Ssthen	    print "autousing $module; "
59898184e3Ssthen		  ."imported $closure_func as $closure_import_func\n"
60898184e3Ssthen		if $autouse::DEBUG;
61898184e3Ssthen	    goto &$closure_import_func;
62898184e3Ssthen	};
63898184e3Ssthen
64898184e3Ssthen	if (defined $proto) {
65898184e3Ssthen	    *$closure_import_func = eval "sub ($proto) { goto &\$load_sub }"
66898184e3Ssthen	        || die;
67898184e3Ssthen	} else {
68898184e3Ssthen	    *$closure_import_func = $load_sub;
69898184e3Ssthen	}
70898184e3Ssthen    }
71898184e3Ssthen}
72898184e3Ssthen
73898184e3Ssthensub vet_import ($) {
74898184e3Ssthen    my $module = shift;
75898184e3Ssthen    if (my $import = $module->can('import')) {
76898184e3Ssthen	croak "autoused module $module has unique import() method"
77898184e3Ssthen	    unless defined(&Exporter::import)
78898184e3Ssthen		   && ($import == \&Exporter::import ||
79898184e3Ssthen		       $import == \&UNIVERSAL::import)
80898184e3Ssthen    }
81898184e3Ssthen}
82898184e3Ssthen
83898184e3Ssthen1;
84898184e3Ssthen
85898184e3Ssthen__END__
86898184e3Ssthen
87898184e3Ssthen=head1 NAME
88898184e3Ssthen
89898184e3Ssthenautouse - postpone load of modules until a function is used
90898184e3Ssthen
91898184e3Ssthen=head1 SYNOPSIS
92898184e3Ssthen
93898184e3Ssthen  use autouse 'Carp' => qw(carp croak);
94898184e3Ssthen  carp "this carp was predeclared and autoused ";
95898184e3Ssthen
96898184e3Ssthen=head1 DESCRIPTION
97898184e3Ssthen
98898184e3SsthenIf the module C<Module> is already loaded, then the declaration
99898184e3Ssthen
100898184e3Ssthen  use autouse 'Module' => qw(func1 func2($;$));
101898184e3Ssthen
102898184e3Ssthenis equivalent to
103898184e3Ssthen
104898184e3Ssthen  use Module qw(func1 func2);
105898184e3Ssthen
106898184e3Ssthenif C<Module> defines func2() with prototype C<($;$)>, and func1() has
107898184e3Ssthenno prototypes.  (At least if C<Module> uses C<Exporter>'s C<import>,
108898184e3Ssthenotherwise it is a fatal error.)
109898184e3Ssthen
110898184e3SsthenIf the module C<Module> is not loaded yet, then the above declaration
111898184e3Ssthendeclares functions func1() and func2() in the current package.  When
112898184e3Ssthenthese functions are called, they load the package C<Module> if needed,
113898184e3Ssthenand substitute themselves with the correct definitions.
114898184e3Ssthen
115898184e3Ssthen=begin _deprecated
116898184e3Ssthen
117898184e3Ssthen   use Module qw(Module::func3);
118898184e3Ssthen
119898184e3Ssthenwill work and is the equivalent to:
120898184e3Ssthen
121898184e3Ssthen   use Module qw(func3);
122898184e3Ssthen
123898184e3SsthenIt is not a very useful feature and has been deprecated.
124898184e3Ssthen
125898184e3Ssthen=end _deprecated
126898184e3Ssthen
127898184e3Ssthen
128898184e3Ssthen=head1 WARNING
129898184e3Ssthen
130898184e3SsthenUsing C<autouse> will move important steps of your program's execution
131898184e3Ssthenfrom compile time to runtime.  This can
132898184e3Ssthen
133898184e3Ssthen=over 4
134898184e3Ssthen
135898184e3Ssthen=item *
136898184e3Ssthen
137898184e3SsthenBreak the execution of your program if the module you C<autouse>d has
138898184e3Ssthensome initialization which it expects to be done early.
139898184e3Ssthen
140898184e3Ssthen=item *
141898184e3Ssthen
142898184e3Ssthenhide bugs in your code since important checks (like correctness of
143898184e3Ssthenprototypes) is moved from compile time to runtime.  In particular, if
144898184e3Ssthenthe prototype you specified on C<autouse> line is wrong, you will not
145898184e3Ssthenfind it out until the corresponding function is executed.  This will be
146898184e3Ssthenvery unfortunate for functions which are not always called (note that
147898184e3Ssthenfor such functions C<autouse>ing gives biggest win, for a workaround
148898184e3Ssthensee below).
149898184e3Ssthen
150898184e3Ssthen=back
151898184e3Ssthen
152898184e3SsthenTo alleviate the second problem (partially) it is advised to write
153898184e3Ssthenyour scripts like this:
154898184e3Ssthen
155898184e3Ssthen  use Module;
156898184e3Ssthen  use autouse Module => qw(carp($) croak(&$));
157898184e3Ssthen  carp "this carp was predeclared and autoused ";
158898184e3Ssthen
159898184e3SsthenThe first line ensures that the errors in your argument specification
160898184e3Ssthenare found early.  When you ship your application you should comment
161898184e3Ssthenout the first line, since it makes the second one useless.
162898184e3Ssthen
163898184e3Ssthen=head1 AUTHOR
164898184e3Ssthen
165898184e3SsthenIlya Zakharevich (ilya@math.ohio-state.edu)
166898184e3Ssthen
167898184e3Ssthen=head1 SEE ALSO
168898184e3Ssthen
169898184e3Ssthenperl(1).
170898184e3Ssthen
171898184e3Ssthen=cut
172