File | /project/perl/lib/UNIVERSAL/require.pm |
Statements Executed | 10 |
Statement Execution Time | 1.13ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
0 | 0 | 0 | 0s | 0s | BEGIN | UNIVERSAL::
0 | 0 | 0 | 0s | 0s | require | UNIVERSAL::
0 | 0 | 0 | 0s | 0s | BEGIN | UNIVERSAL::require::
0 | 0 | 0 | 0s | 0s | use | UNIVERSAL::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package UNIVERSAL::require; | ||||
2 | 1 | 6µs | $UNIVERSAL::require::VERSION = '0.11'; | ||
3 | |||||
4 | # We do this because UNIVERSAL.pm uses CORE::require(). We're going | ||||
5 | # to put our own require() into UNIVERSAL and that makes an ambiguity. | ||||
6 | # So we load it up beforehand to avoid that. | ||||
7 | 1 | 400µs | BEGIN { require UNIVERSAL } | ||
8 | |||||
9 | package UNIVERSAL; | ||||
10 | |||||
11 | 3 | 89µs | 1 | 24µs | use strict; # spent 24µs making 1 call to strict::import |
12 | |||||
13 | 3 | 619µs | 1 | 130µs | use vars qw($Level); # spent 130µs making 1 call to vars::import |
14 | 1 | 5µs | $Level = 0; | ||
15 | |||||
16 | =pod | ||||
17 | |||||
18 | =head1 NAME | ||||
19 | |||||
20 | UNIVERSAL::require - require() modules from a variable | ||||
21 | |||||
22 | =head1 SYNOPSIS | ||||
23 | |||||
24 | # This only needs to be said once in your program. | ||||
25 | require UNIVERSAL::require; | ||||
26 | |||||
27 | # Same as "require Some::Module" | ||||
28 | my $module = 'Some::Module'; | ||||
29 | $module->require or die $@; | ||||
30 | |||||
31 | # Same as "use Some::Module" | ||||
32 | BEGIN { $module->use or die $@ } | ||||
33 | |||||
34 | |||||
35 | =head1 DESCRIPTION | ||||
36 | |||||
37 | If you've ever had to do this... | ||||
38 | |||||
39 | eval "require $module"; | ||||
40 | |||||
41 | to get around the bareword caveats on require(), this module is for | ||||
42 | you. It creates a universal require() class method that will work | ||||
43 | with every Perl module and its secure. So instead of doing some | ||||
44 | arcane eval() work, you can do this: | ||||
45 | |||||
46 | $module->require; | ||||
47 | |||||
48 | It doesn't save you much typing, but it'll make alot more sense to | ||||
49 | someone who's not a ninth level Perl acolyte. | ||||
50 | |||||
51 | =head1 Methods | ||||
52 | |||||
53 | =head3 require | ||||
54 | |||||
55 | my $return_val = $module->require or die $@; | ||||
56 | my $return_val = $module->require($version) or die $@; | ||||
57 | |||||
58 | This works exactly like Perl's require, except without the bareword | ||||
59 | restriction, and it doesn't die. Since require() is placed in the | ||||
60 | UNIVERSAL namespace, it will work on B<any> module. You just have to | ||||
61 | use UNIVERSAL::require somewhere in your code. | ||||
62 | |||||
63 | Should the module require fail, or not be a high enough $version, it | ||||
64 | will simply return false and B<not die>. The error will be in | ||||
65 | $@ as well as $UNIVERSAL::require::ERROR. | ||||
66 | |||||
67 | $module->require or die $@; | ||||
68 | |||||
69 | =cut | ||||
70 | |||||
71 | sub require { | ||||
72 | my($module, $want_version) = @_; | ||||
73 | |||||
74 | $UNIVERSAL::require::ERROR = ''; | ||||
75 | |||||
76 | die("UNIVERSAL::require() can only be run as a class method") | ||||
77 | if ref $module; | ||||
78 | |||||
79 | die("UNIVERSAL::require() takes no or one arguments") if @_ > 2; | ||||
80 | |||||
81 | my($call_package, $call_file, $call_line) = caller($Level); | ||||
82 | |||||
83 | # Load the module. | ||||
84 | my $file = $module . '.pm'; | ||||
85 | $file =~ s{::}{/}g; | ||||
86 | |||||
87 | # For performance reasons, check if its already been loaded. This makes | ||||
88 | # things about 4 times faster. | ||||
89 | return 1 if $INC{$file}; | ||||
90 | |||||
91 | my $return = eval qq{ | ||||
92 | #line $call_line "$call_file" | ||||
93 | CORE::require(\$file); | ||||
94 | }; | ||||
95 | |||||
96 | # Check for module load failure. | ||||
97 | if( $@ ) { | ||||
98 | $UNIVERSAL::require::ERROR = $@; | ||||
99 | return $return; | ||||
100 | } | ||||
101 | |||||
102 | # Module version check. | ||||
103 | if( @_ == 2 ) { | ||||
104 | eval qq{ | ||||
105 | #line $call_line "$call_file" | ||||
106 | \$module->VERSION($want_version); | ||||
107 | }; | ||||
108 | |||||
109 | if( $@ ) { | ||||
110 | $UNIVERSAL::require::ERROR = $@; | ||||
111 | return 0; | ||||
112 | } | ||||
113 | } | ||||
114 | |||||
115 | return $return; | ||||
116 | } | ||||
117 | |||||
118 | |||||
119 | =head3 use | ||||
120 | |||||
121 | my $require_return = $module->use or die $@; | ||||
122 | my $require_return = $module->use(@imports) or die $@; | ||||
123 | |||||
124 | Like C<UNIVERSAL::require>, this allows you to C<use> a $module without | ||||
125 | having to eval to work around the bareword requirement. It returns the | ||||
126 | same as require. | ||||
127 | |||||
128 | Should either the require or the import fail it will return false. The | ||||
129 | error will be in $@. | ||||
130 | |||||
131 | If possible, call this inside a BEGIN block to emulate a normal C<use> | ||||
132 | as closely as possible. | ||||
133 | |||||
134 | BEGIN { $module->use } | ||||
135 | |||||
136 | =cut | ||||
137 | |||||
138 | sub use { | ||||
139 | my($module, @imports) = @_; | ||||
140 | |||||
141 | local $Level = 1; | ||||
142 | my $return = $module->require or return 0; | ||||
143 | |||||
144 | my($call_package, $call_file, $call_line) = caller; | ||||
145 | |||||
146 | eval qq{ | ||||
147 | package $call_package; | ||||
148 | #line $call_line "$call_file" | ||||
149 | \$module->import(\@imports); | ||||
150 | }; | ||||
151 | |||||
152 | if( $@ ) { | ||||
153 | $UNIVERSAL::require::ERROR = $@; | ||||
154 | return 0; | ||||
155 | } | ||||
156 | |||||
157 | return $return; | ||||
158 | } | ||||
159 | |||||
160 | |||||
161 | =head1 SECURITY NOTES | ||||
162 | |||||
163 | UNIVERSAL::require makes use of C<eval STRING>. In previous versions | ||||
164 | of UNIVERSAL::require it was discovered that one could craft a class | ||||
165 | name which would result in code being executed. This hole has been | ||||
166 | closed. The only variables now exposed to C<eval STRING> are the | ||||
167 | caller's package, filename and line which are not tainted. | ||||
168 | |||||
169 | UNIVERSAL::require is taint clean. | ||||
170 | |||||
171 | |||||
172 | =head1 COPYRIGHT | ||||
173 | |||||
174 | Copyright 2001, 2005 by Michael G Schwern E<lt>schwern@pobox.comE<gt>. | ||||
175 | |||||
176 | This program is free software; you can redistribute it and/or | ||||
177 | modify it under the same terms as Perl itself. | ||||
178 | |||||
179 | See F<http://www.perl.com/perl/misc/Artistic.html> | ||||
180 | |||||
181 | |||||
182 | =head1 AUTHOR | ||||
183 | |||||
184 | Michael G Schwern <schwern@pobox.com> | ||||
185 | |||||
186 | |||||
187 | =head1 SEE ALSO | ||||
188 | |||||
189 | L<Module::Load>, L<perlfunc/require>, L<http://dev.perl.org/rfc/253.pod> | ||||
190 | |||||
191 | =cut | ||||
192 | |||||
193 | |||||
194 | 1 | 12µs | 1; |