line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=head1 NAME |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
AutoReloader - Lazy loading and reloading of anonymous subroutines |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
=head1 SYNOPSIS |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
use AutoReloader; |
8
|
|
|
|
|
|
|
my $sub = AutoReloader -> new ($file, $checksub, $autoprefix); |
9
|
|
|
|
|
|
|
$result = $sub -> (@args); |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
$sub -> check (0); # turn source file checking off for $sub |
12
|
|
|
|
|
|
|
$sub -> checksub ($coderef); # provide alternative checking routine |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use AutoReloader qw (AUTOLOAD); |
15
|
|
|
|
|
|
|
AutoReloader -> check (1); # turn source file checking on |
16
|
|
|
|
|
|
|
$result = somefunc (@args); |
17
|
|
|
|
|
|
|
*somefunc{CODE}->check(0); # turn off checking for this named sub |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
=head1 DESCRIPTION |
20
|
|
|
|
|
|
|
|
21
|
|
|
|
|
|
|
AutoReloader provides lazy loading like AutoLoader, but for function files |
22
|
|
|
|
|
|
|
which return an anonymous subroutine upon require. |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
Before requiring that file, it is checked via some subroutine returning |
25
|
|
|
|
|
|
|
a value (default is mtime). The returned value is remembered. At each |
26
|
|
|
|
|
|
|
call to that sub the check subroutine is run again, and if the returned |
27
|
|
|
|
|
|
|
value changed, the source file is reloaded. |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
Importing the AUTOLOAD method provides for lazy loading of anonsubs as |
30
|
|
|
|
|
|
|
named subs. The wrapped anonsub will be assigned to a symbol table entry |
31
|
|
|
|
|
|
|
named after the filename root of the function source file. |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
=head1 METHODS |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
=over 4 |
36
|
|
|
|
|
|
|
|
37
|
|
|
|
|
|
|
=item new ($file, $checksubref, $autoprefix) |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
subroutine constructor. $file can be the path to some function file or |
40
|
|
|
|
|
|
|
a function name which will be expanded to $autoprefix/__PACKAGE__/$function.al |
41
|
|
|
|
|
|
|
and searched for in @INC. $checksubref and $autoprefix are optional. |
42
|
|
|
|
|
|
|
If they are not provided, the default class settings are used. |
43
|
|
|
|
|
|
|
|
44
|
|
|
|
|
|
|
=item auto ($autoprefix) |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
set or get the default autoprefix. Default is 'auto', just as with AutoLoader: |
47
|
|
|
|
|
|
|
for e.g. POSIX::rand the source file would be auto/POSIX/rand.al . AutoReloader |
48
|
|
|
|
|
|
|
lets you replace the 'auto' part of the path with something else. Class method |
49
|
|
|
|
|
|
|
(for now). |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
=item suffix ($suffix) |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
set or get the suffix of your autoloaded files (e.g. '.al', '.pl', '.tmpl') |
54
|
|
|
|
|
|
|
as a package variable. |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item check (1) |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
set or get the check flag. Turn checking on by setting this to some true value. |
59
|
|
|
|
|
|
|
Default is off. Class and object method, i.e. AutoReloader->check(1) sets the |
60
|
|
|
|
|
|
|
default to on, $sub->check(1) sets checking for a subroutine. For now, there's |
61
|
|
|
|
|
|
|
no way to inculcate the class default on subs with a private check flag. |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
=item checksub ($coderef) |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
set the checking subroutine. Class and object method. This subroutine will be |
66
|
|
|
|
|
|
|
invoked with a subroutines source filename (full path) every time the sub for |
67
|
|
|
|
|
|
|
which it is configured - but only if check for that subroutine is true -, and |
68
|
|
|
|
|
|
|
should return some value special to that file. |
69
|
|
|
|
|
|
|
Default is 'sub { (stat $_[0]) [9] }', i.e. mtime. |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
=back |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
=head1 SEE ALSO |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
AutoLoader, AutoSplit, DBIx::VersionedSubs |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
=head1 BUGS |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
AutoReloader subroutines are always reported as __ANON__ (e.g. with Carp::cluck), |
80
|
|
|
|
|
|
|
even if they are assigned to a symbol table entry. Which might not be a bug. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
There might be others. |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=head1 Author |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
shmem |
87
|
|
|
|
|
|
|
|
88
|
|
|
|
|
|
|
=head1 CREDITS |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
Many thanks to thospel, Corion, diotalevi, tye and chromatic (these are their |
91
|
|
|
|
|
|
|
http://perlmonks.org nicks) for review and most valuable hints. |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
=head1 COPYRIGHT |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
Copyright 2007 - 2021 by shmem |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
98
|
|
|
|
|
|
|
under the same terms as Perl itself. |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
=cut |
101
|
|
|
|
|
|
|
|
102
|
|
|
|
|
|
|
package AutoReloader; |
103
|
|
|
|
|
|
|
|
104
|
4
|
|
|
4
|
|
284885
|
use strict; |
|
4
|
|
|
|
|
34
|
|
|
4
|
|
|
|
|
123
|
|
105
|
4
|
|
|
4
|
|
21
|
use warnings; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
122
|
|
106
|
4
|
|
|
4
|
|
31
|
use Scalar::Util; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
168
|
|
107
|
4
|
|
|
4
|
|
24
|
use File::Spec; |
|
4
|
|
|
|
|
9
|
|
|
4
|
|
|
|
|
203
|
|
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
our $VERSION = 0.03; |
110
|
|
|
|
|
|
|
|
111
|
4
|
|
|
4
|
|
29
|
use vars qw($Debug %AL); |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
4423
|
|
112
|
|
|
|
|
|
|
$Debug = 0; |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
sub new { |
115
|
2
|
|
|
2
|
1
|
318
|
my $class = shift; |
116
|
2
|
|
|
|
|
6
|
my $caller = caller; |
117
|
2
|
|
|
|
|
8
|
my $sub = gensub ($caller,@_); |
118
|
|
|
|
|
|
|
|
119
|
2
|
|
|
|
|
7
|
bless $sub, $class; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
|
122
|
|
|
|
|
|
|
sub auto { |
123
|
5
|
|
|
5
|
1
|
831
|
shift if __PACKAGE__ || $_[0] eq (caller(0))[0]; |
124
|
5
|
100
|
|
|
|
27
|
$AL {'auto'} = shift if @_; |
125
|
5
|
|
|
|
|
21
|
$AL {'auto'}; |
126
|
|
|
|
|
|
|
} |
127
|
|
|
|
|
|
|
|
128
|
|
|
|
|
|
|
sub check { |
129
|
8
|
|
|
8
|
1
|
2002979
|
my $self = shift; |
130
|
8
|
100
|
|
|
|
32
|
if(ref($self)) { |
131
|
3
|
50
|
|
|
|
21
|
${ $AL {'Sub'} -> {Scalar::Util::refaddr ($self)} -> {'check'} } |
|
3
|
|
|
|
|
29
|
|
132
|
|
|
|
|
|
|
= shift if @_; |
133
|
3
|
|
|
|
|
9
|
${ $AL {'Sub'} -> {Scalar::Util::refaddr ($self)} -> {'check'} }; |
|
3
|
|
|
|
|
16
|
|
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
else { |
136
|
5
|
|
|
|
|
11
|
$AL {'check'} = shift; |
137
|
5
|
|
|
|
|
9
|
$AL {'check'}; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
} |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
sub checksub { |
142
|
6
|
|
|
6
|
1
|
1110
|
my $self = shift; |
143
|
6
|
100
|
|
|
|
21
|
if(ref($self)) { |
144
|
2
|
100
|
|
|
|
12
|
${ $AL {'Sub'} -> {Scalar::Util::refaddr ($self)} -> {'checksub'} } |
|
1
|
|
|
|
|
7
|
|
145
|
|
|
|
|
|
|
= shift if @_; |
146
|
2
|
|
|
|
|
5
|
${ $AL {'Sub'} -> {Scalar::Util::refaddr ($self)} -> {'checksub'} }; |
|
2
|
|
|
|
|
16
|
|
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
else { |
149
|
4
|
50
|
|
|
|
18
|
$AL {'checksub'} = shift if @_; |
150
|
4
|
|
|
|
|
8
|
$AL {'checksub'}; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
} |
153
|
|
|
|
|
|
|
sub suffix { |
154
|
0
|
|
|
0
|
1
|
0
|
shift if __PACKAGE__ || $_[0] eq (caller(0))[0]; |
155
|
0
|
0
|
|
|
|
0
|
$AL {'suffix'} = shift if @_; |
156
|
0
|
|
|
|
|
0
|
$AL {'suffix'}; |
157
|
|
|
|
|
|
|
} |
158
|
|
|
|
|
|
|
# default check subroutine |
159
|
|
|
|
|
|
|
checksub ( __PACKAGE__, sub { (stat $_[0]) [9] } ); |
160
|
|
|
|
|
|
|
# default is not checking |
161
|
|
|
|
|
|
|
check ( __PACKAGE__, 0); |
162
|
|
|
|
|
|
|
|
163
|
|
|
|
|
|
|
# gensub - returns an anonymous subroutine. |
164
|
|
|
|
|
|
|
# Parameters: |
165
|
|
|
|
|
|
|
# if one: filename (full path) |
166
|
|
|
|
|
|
|
# if more: package, filename [, checkfuncref [, auto ]] |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub gensub { |
169
|
16
|
50
|
|
16
|
0
|
51
|
my $package = scalar(@_) == 1 ? caller : shift; |
170
|
16
|
|
|
|
|
24
|
my $file = shift; |
171
|
16
|
|
33
|
|
|
65
|
my $chkfunc = shift || $AL {'checksub'}; |
172
|
16
|
|
50
|
|
|
46
|
my $auto = shift || $AL {'auto'} || 'auto'; |
173
|
16
|
|
|
|
|
21
|
my $function; |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
{ |
176
|
16
|
|
|
|
|
17
|
($function = pop (@{[ File::Spec->splitpath($file) ]}) ) =~ s/\..*//; |
|
16
|
|
|
|
|
20
|
|
|
16
|
|
|
|
|
246
|
|
177
|
|
|
|
|
|
|
|
178
|
16
|
50
|
50
|
|
|
101
|
$file .= $AL {'suffix'} || '.al' unless $file =~ /\.\w+$/; |
179
|
16
|
50
|
|
|
|
326
|
unless (-e $file) { |
180
|
16
|
|
|
|
|
39
|
my ($filename, $seen); |
181
|
|
|
|
|
|
|
{ |
182
|
16
|
|
|
|
|
25
|
$filename = File::Spec -> catfile ($auto, $package, $file); |
|
23
|
|
|
|
|
222
|
|
183
|
23
|
|
|
|
|
76
|
foreach my $d ('.',@INC) { # check current working dir first |
184
|
198
|
|
|
|
|
1324
|
my $f = File::Spec -> catfile ($d,$filename); |
185
|
198
|
100
|
|
|
|
2227
|
if (-e $f) { |
186
|
10
|
|
|
|
|
29
|
$file = $f; |
187
|
10
|
|
|
|
|
23
|
last; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
23
|
100
|
|
|
|
48
|
last if $seen; |
191
|
16
|
100
|
|
|
|
182
|
unless (-e $file) { |
192
|
|
|
|
|
|
|
# redo the search with a truncated filename |
193
|
7
|
|
|
|
|
22
|
$file =~ s/(\w{12,})(\.\w+)$/substr($1,0,11).$2/e; |
|
1
|
|
|
|
|
7
|
|
194
|
7
|
|
|
|
|
11
|
$seen++; |
195
|
7
|
|
|
|
|
11
|
redo; |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
die |
199
|
16
|
100
|
|
|
|
273
|
"Can't locate function file '$filename' for package '$package'\n" |
200
|
|
|
|
|
|
|
unless -e $file; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
|
204
|
10
|
100
|
|
|
|
67
|
if (my $addr = $AL {'Inc'} -> {"$package\::$function"} ) { |
205
|
1
|
|
|
|
|
8
|
return $AL {Sub} -> {$addr} -> {'outer'}; |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
else { |
208
|
|
|
|
|
|
|
# file not known yet |
209
|
9
|
|
|
|
|
14
|
my $inner; |
210
|
9
|
|
|
|
|
15
|
my $h = {}; |
211
|
9
|
|
|
|
|
28
|
my $cr = $chkfunc -> ($file); |
212
|
9
|
|
|
|
|
34
|
my $subname = "$package\::$function"; |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
$h = { |
215
|
|
|
|
|
|
|
file => $file, |
216
|
9
|
|
|
|
|
56
|
check => \$AL {'check'}, |
217
|
|
|
|
|
|
|
checksub => \$chkfunc, |
218
|
|
|
|
|
|
|
checkref => \$cr, |
219
|
|
|
|
|
|
|
function => $subname, |
220
|
|
|
|
|
|
|
}; |
221
|
|
|
|
|
|
|
|
222
|
9
|
100
|
|
|
|
28
|
my $outer = load ($package, $file, $h) or die $@; |
223
|
8
|
|
|
|
|
29
|
my $outeraddr = Scalar::Util::refaddr ($outer); |
224
|
|
|
|
|
|
|
|
225
|
8
|
|
|
|
|
14
|
$h -> {'outer'} = $outer; |
226
|
8
|
|
|
|
|
27
|
Scalar::Util::weaken ($h -> {'outer'}); |
227
|
|
|
|
|
|
|
|
228
|
8
|
|
|
|
|
24
|
$AL{Sub} -> {$outeraddr} = $h; |
229
|
8
|
|
|
|
|
21
|
$AL{Inc} -> {$subname} = $outeraddr; |
230
|
8
|
|
|
|
|
51
|
return bless $outer, __PACKAGE__; |
231
|
|
|
|
|
|
|
} |
232
|
|
|
|
|
|
|
}; |
233
|
|
|
|
|
|
|
{ |
234
|
|
|
|
|
|
|
my $load = \&load; |
235
|
|
|
|
|
|
|
sub load { |
236
|
14
|
|
|
14
|
0
|
45
|
my ($package, $file, $h) = @_; |
237
|
14
|
|
|
|
|
66
|
delete $INC {$file}; |
238
|
14
|
|
|
|
|
1030
|
my $ref = eval "package $package; require '$file'"; |
239
|
|
|
|
|
|
|
#warn $@ if $@; |
240
|
14
|
100
|
|
|
|
196
|
return undef if $@; |
241
|
|
|
|
|
|
|
{ |
242
|
|
|
|
|
|
|
# just in case the require dinn' return a ref - |
243
|
|
|
|
|
|
|
# then a named subroutine has been loaded. |
244
|
|
|
|
|
|
|
# All other cases are errors. |
245
|
13
|
100
|
66
|
|
|
25
|
unless ( |
|
13
|
|
|
|
|
99
|
|
246
|
|
|
|
|
|
|
Scalar::Util::reftype($ref) |
247
|
|
|
|
|
|
|
and |
248
|
|
|
|
|
|
|
Scalar::Util::reftype($ref) eq 'CODE') { |
249
|
5
|
|
|
|
|
7
|
$ref = \&{$h -> {'function'}}; |
|
5
|
|
|
|
|
16
|
|
250
|
4
|
|
|
4
|
|
32
|
no strict 'refs'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
150
|
|
251
|
4
|
|
|
4
|
|
22
|
no warnings 'redefine'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
1310
|
|
252
|
5
|
50
|
|
|
|
12
|
*{$h -> {'function'} } = $h ->{'outer'} if $h -> {'outer'}; |
|
0
|
|
|
|
|
0
|
|
253
|
|
|
|
|
|
|
} |
254
|
13
|
|
|
|
|
21
|
${$h->{inner}} = $ref; |
|
13
|
|
|
|
|
55
|
|
255
|
|
|
|
|
|
|
|
256
|
|
|
|
|
|
|
my $sub = sub { |
257
|
22
|
|
|
22
|
|
2021411
|
my $cr = $h -> {'checkref'}; |
258
|
22
|
100
|
66
|
|
|
38
|
if( ${ $h -> {'check'} } and ${ $h-> {'checksub'} } |
|
22
|
|
100
|
|
|
114
|
|
|
6
|
|
|
|
|
36
|
|
259
|
|
|
|
|
|
|
and |
260
|
6
|
|
|
|
|
21
|
( my $c = ${ $h->{checksub} } -> ($file) ) != $$cr) { |
261
|
5
|
50
|
|
|
|
86
|
warn "reloading $file" if $Debug; |
262
|
5
|
|
|
|
|
24
|
$$cr = $c; |
263
|
5
|
|
|
|
|
22
|
$load -> ($package, $file, $h); |
264
|
|
|
|
|
|
|
} |
265
|
22
|
|
|
|
|
97
|
goto ${ $h -> {'inner'} }; |
|
22
|
|
|
|
|
91
|
|
266
|
13
|
|
|
|
|
92
|
}; |
267
|
|
|
|
|
|
|
} |
268
|
|
|
|
|
|
|
} |
269
|
|
|
|
|
|
|
} |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
sub DESTROY { |
272
|
2
|
|
|
2
|
|
747
|
my $outeraddr = Scalar::Util::refaddr ($_[0]); |
273
|
2
|
|
|
|
|
7
|
my $h = $AL {'Sub'} -> {$outeraddr}; |
274
|
2
|
|
|
|
|
9
|
delete $AL {'Inc'} -> { $h -> {'function'}}; |
275
|
2
|
|
|
|
|
178
|
delete $AL {'Sub'} -> {$outeraddr}; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
sub AUTOLOAD { |
279
|
4
|
|
|
4
|
|
31
|
no strict; |
|
4
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
735
|
|
280
|
10
|
|
|
10
|
|
3072
|
my $sub = $AUTOLOAD; |
281
|
10
|
|
|
|
|
18
|
my ($pkg, $func, $filename); |
282
|
|
|
|
|
|
|
{ |
283
|
10
|
|
|
|
|
13
|
($pkg, $func) = ($sub =~ /(.*)::([^:]+)$/); |
|
10
|
|
|
|
|
115
|
|
284
|
10
|
|
|
|
|
102
|
$pkg = File::Spec -> catdir (split /::/, $pkg); |
285
|
|
|
|
|
|
|
} |
286
|
10
|
|
|
|
|
23
|
my $save = $@; |
287
|
10
|
|
|
|
|
48
|
local $!; # Do not munge the value. |
288
|
10
|
|
|
|
|
17
|
my $ref; |
289
|
10
|
|
100
|
|
|
12
|
eval { local $SIG{__DIE__}; $ref = gensub ($pkg, $func, '', $AL{'auto'} || 'auto'); }; |
|
10
|
|
|
|
|
35
|
|
|
10
|
|
|
|
|
57
|
|
290
|
10
|
100
|
|
|
|
29
|
if ($@) { |
291
|
4
|
100
|
|
|
|
14
|
if (substr ($sub,-9) eq '::DESTROY') { |
292
|
4
|
|
|
4
|
|
28
|
no strict 'refs'; |
|
4
|
|
|
|
|
7
|
|
|
4
|
|
|
|
|
486
|
|
293
|
2
|
|
|
0
|
|
17
|
*$sub = sub {}; |
294
|
2
|
|
|
|
|
4
|
$@ = undef; |
295
|
|
|
|
|
|
|
} |
296
|
4
|
100
|
|
|
|
9
|
if ($@){ |
297
|
2
|
|
|
|
|
3
|
my $error = $@; |
298
|
2
|
|
|
|
|
23
|
require Carp; |
299
|
2
|
|
|
|
|
232
|
Carp::croak($error); |
300
|
|
|
|
|
|
|
} |
301
|
|
|
|
|
|
|
} |
302
|
8
|
|
|
|
|
14
|
$@ = $save; |
303
|
8
|
100
|
|
|
|
37
|
return unless $ref; |
304
|
4
|
|
|
4
|
|
49
|
no warnings 'redefine'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
570
|
|
305
|
6
|
|
|
|
|
20
|
*$AUTOLOAD = $ref; |
306
|
6
|
|
|
|
|
30
|
goto $ref; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
# below are shameless plugs from AutoLoader 5.63 |
310
|
|
|
|
|
|
|
|
311
|
|
|
|
|
|
|
sub import { |
312
|
7
|
|
|
7
|
|
1934
|
my $pkg = shift; |
313
|
7
|
|
|
|
|
16
|
my $callpkg = caller; |
314
|
7
|
50
|
|
|
|
27
|
if ($pkg eq 'AutoReloader') { |
315
|
7
|
100
|
66
|
|
|
67
|
if ( @_ and $_[0] =~ /^&?AUTOLOAD$/ ) { |
316
|
4
|
|
|
4
|
|
27
|
no strict 'refs'; |
|
4
|
|
|
|
|
22
|
|
|
4
|
|
|
|
|
406
|
|
317
|
4
|
|
|
|
|
12
|
*{ $callpkg . '::AUTOLOAD' } = \&AUTOLOAD; |
|
4
|
|
|
|
|
22
|
|
318
|
4
|
|
|
|
|
10
|
*{ $callpkg . '::can' } = \&can; |
|
4
|
|
|
|
|
1665
|
|
319
|
|
|
|
|
|
|
} |
320
|
|
|
|
|
|
|
} |
321
|
|
|
|
|
|
|
} |
322
|
|
|
|
|
|
|
|
323
|
|
|
|
|
|
|
sub unimport { |
324
|
2
|
|
|
2
|
|
605
|
my $callpkg = caller; |
325
|
|
|
|
|
|
|
|
326
|
4
|
|
|
4
|
|
27
|
no strict 'refs'; |
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
796
|
|
327
|
|
|
|
|
|
|
|
328
|
2
|
|
|
|
|
6
|
for my $exported (qw( AUTOLOAD can )) { |
329
|
4
|
|
|
|
|
7
|
my $symname = $callpkg . '::' . $exported; |
330
|
4
|
100
|
|
|
|
4
|
undef *{ $symname } if \&{ $symname } == \&{ $exported }; |
|
2
|
|
|
|
|
5
|
|
|
4
|
|
|
|
|
12
|
|
|
4
|
|
|
|
|
15
|
|
331
|
4
|
|
|
|
|
7
|
*{ $symname } = \&{ $symname }; |
|
4
|
|
|
|
|
18
|
|
|
4
|
|
|
|
|
6
|
|
332
|
|
|
|
|
|
|
} |
333
|
|
|
|
|
|
|
} |
334
|
|
|
|
|
|
|
|
335
|
|
|
|
|
|
|
sub can { |
336
|
5
|
|
|
5
|
0
|
742
|
my ($self, $func) = @_; |
337
|
5
|
|
|
|
|
28
|
my $parent = $self->SUPER::can( $func ); |
338
|
5
|
100
|
|
|
|
14
|
return $parent if $parent; |
339
|
4
|
|
33
|
|
|
11
|
my $pkg = ref( $self ) || $self; |
340
|
4
|
|
|
|
|
6
|
local $@; |
341
|
4
|
|
|
|
|
5
|
my $ref; |
342
|
4
|
100
|
50
|
|
|
6
|
$ref = eval { local $SIG{__DIE__}; $ref = gensub ($pkg, $func, '', $AL{'auto'} || 'auto'); } |
|
4
|
|
|
|
|
14
|
|
|
4
|
|
|
|
|
20
|
|
343
|
|
|
|
|
|
|
or return undef; |
344
|
4
|
|
|
4
|
|
29
|
no strict 'refs'; |
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
132
|
|
345
|
4
|
|
|
4
|
|
30
|
no warnings 'redefine'; |
|
4
|
|
|
|
|
15
|
|
|
4
|
|
|
|
|
304
|
|
346
|
1
|
|
|
|
|
2
|
*{ $pkg . '::' . $func } = $ref; |
|
1
|
|
|
|
|
5
|
|
347
|
1
|
|
|
|
|
3
|
$ref; |
348
|
|
|
|
|
|
|
} |
349
|
|
|
|
|
|
|
1; |
350
|
|
|
|
|
|
|
__END__ |