I don't think trying to bracket the hires time with lores
[p5sagit/p5-mst-13.2.git] / lib / constant.pm
1 package constant;
2
3 use strict;
4 use 5.006_00;
5 use warnings::register;
6
7 our($VERSION, %declared);
8 $VERSION = '1.04';
9
10 #=======================================================================
11
12 # Some names are evil choices.
13 my %keywords = map +($_, 1), qw{ BEGIN INIT CHECK END DESTROY AUTOLOAD };
14
15 my %forced_into_main = map +($_, 1),
16     qw{ STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG };
17
18 my %forbidden = (%keywords, %forced_into_main);
19
20 #=======================================================================
21 # import() - import symbols into user's namespace
22 #
23 # What we actually do is define a function in the caller's namespace
24 # which returns the value. The function we create will normally
25 # be inlined as a constant, thereby avoiding further sub calling 
26 # overhead.
27 #=======================================================================
28 sub import {
29     my $class = shift;
30     return unless @_;                   # Ignore 'use constant;'
31     my %constants = ();
32     my $multiple  = ref $_[0];
33
34     if ( $multiple ) {
35         if (ref $_[0] ne 'HASH') {
36             require Carp;
37             Carp::croak("Invalid reference type '".ref(shift)."' not 'HASH'");
38         }
39         %constants = %{+shift};
40     } else {
41         $constants{+shift} = undef;
42     }
43
44     foreach my $name ( keys %constants ) {
45         unless (defined $name) {
46             require Carp;
47             Carp::croak("Can't use undef as constant name");
48         }
49         my $pkg = caller;
50
51         # Normal constant name
52         if ($name =~ /^_?[^\W_0-9]\w*\z/ and !$forbidden{$name}) {
53             # Everything is okay
54
55         # Name forced into main, but we're not in main. Fatal.
56         } elsif ($forced_into_main{$name} and $pkg ne 'main') {
57             require Carp;
58             Carp::croak("Constant name '$name' is forced into main::");
59
60         # Starts with double underscore. Fatal.
61         } elsif ($name =~ /^__/) {
62             require Carp;
63             Carp::croak("Constant name '$name' begins with '__'");
64
65         # Maybe the name is tolerable
66         } elsif ($name =~ /^[A-Za-z_]\w*\z/) {
67             # Then we'll warn only if you've asked for warnings
68             if (warnings::enabled()) {
69                 if ($keywords{$name}) {
70                     warnings::warn("Constant name '$name' is a Perl keyword");
71                 } elsif ($forced_into_main{$name}) {
72                     warnings::warn("Constant name '$name' is " .
73                         "forced into package main::");
74                 } else {
75                     # Catch-all - what did I miss? If you get this error,
76                     # please let me know what your constant's name was.
77                     # Write to <rootbeer@redcat.com>. Thanks!
78                     warnings::warn("Constant name '$name' has unknown problems");
79                 }
80             }
81
82         # Looks like a boolean
83         # use constant FRED == fred;
84         } elsif ($name =~ /^[01]?\z/) {
85             require Carp;
86             if (@_) {
87                 Carp::croak("Constant name '$name' is invalid");
88             } else {
89                 Carp::croak("Constant name looks like boolean value");
90             }
91
92         } else {
93            # Must have bad characters
94             require Carp;
95             Carp::croak("Constant name '$name' has invalid characters");
96         }
97
98         {
99             no strict 'refs';
100             my $full_name = "${pkg}::$name";
101             $declared{$full_name}++;
102             if ($multiple) {
103                 my $scalar = $constants{$name};
104                 *$full_name = sub () { $scalar };
105             } else {
106                 if (@_ == 1) {
107                     my $scalar = $_[0];
108                     *$full_name = sub () { $scalar };
109                 } elsif (@_) {
110                     my @list = @_;
111                     *$full_name = sub () { @list };
112                 } else {
113                     *$full_name = sub () { };
114                 }
115             }
116         }
117     }
118 }
119
120 1;
121
122 __END__
123
124 =head1 NAME
125
126 constant - Perl pragma to declare constants
127
128 =head1 SYNOPSIS
129
130     use constant PI    => 4 * atan2(1, 1);
131     use constant DEBUG => 0;
132
133     print "Pi equals ", PI, "...\n" if DEBUG;
134
135     use constant {
136         SEC   => 0,
137         MIN   => 1,
138         HOUR  => 2,
139         MDAY  => 3,
140         MON   => 4,
141         YEAR  => 5,
142         WDAY  => 6,
143         YDAY  => 7,
144         ISDST => 8,
145     };
146
147     use constant WEEKDAYS => qw(
148         Sunday Monday Tuesday Wednesday Thursday Friday Saturday
149     );
150
151     print "Today is ", (WEEKDAYS)[ (localtime)[WDAY] ], ".\n";
152
153 =head1 DESCRIPTION
154
155 This will declare a symbol to be a constant with the given value.
156
157 When you declare a constant such as C<PI> using the method shown
158 above, each machine your script runs upon can have as many digits
159 of accuracy as it can use. Also, your program will be easier to
160 read, more likely to be maintained (and maintained correctly), and
161 far less likely to send a space probe to the wrong planet because
162 nobody noticed the one equation in which you wrote C<3.14195>.
163
164 When a constant is used in an expression, perl replaces it with its
165 value at compile time, and may then optimize the expression further.
166 In particular, any code in an C<if (CONSTANT)> block will be optimized
167 away if the constant is false.
168
169 =head1 NOTES
170
171 As with all C<use> directives, defining a constant happens at
172 compile time. Thus, it's probably not correct to put a constant
173 declaration inside of a conditional statement (like C<if ($foo)
174 { use constant ... }>).
175
176 Constants defined using this module cannot be interpolated into
177 strings like variables.  However, concatenation works just fine:
178
179     print "Pi equals PI...\n";        # WRONG: does not expand "PI"
180     print "Pi equals ".PI."...\n";    # right
181
182 Even though a reference may be declared as a constant, the reference may
183 point to data which may be changed, as this code shows.
184
185     use constant ARRAY => [ 1,2,3,4 ];
186     print ARRAY->[1];
187     ARRAY->[1] = " be changed";
188     print ARRAY->[1];
189
190 Dereferencing constant references incorrectly (such as using an array
191 subscript on a constant hash reference, or vice versa) will be trapped at
192 compile time.
193
194 Constants belong to the package they are defined in.  To refer to a
195 constant defined in another package, specify the full package name, as
196 in C<Some::Package::CONSTANT>.  Constants may be exported by modules,
197 and may also be called as either class or instance methods, that is,
198 as C<< Some::Package->CONSTANT >> or as C<< $obj->CONSTANT >> where
199 C<$obj> is an instance of C<Some::Package>.  Subclasses may define
200 their own constants to override those in their base class.
201
202 The use of all caps for constant names is merely a convention,
203 although it is recommended in order to make constants stand out
204 and to help avoid collisions with other barewords, keywords, and
205 subroutine names. Constant names must begin with a letter or
206 underscore. Names beginning with a double underscore are reserved. Some
207 poor choices for names will generate warnings, if warnings are enabled at
208 compile time.
209
210 =head2 List constants
211
212 Constants may be lists of more (or less) than one value.  A constant
213 with no values evaluates to C<undef> in scalar context.  Note that
214 constants with more than one value do I<not> return their last value in
215 scalar context as one might expect.  They currently return the number
216 of values, but B<this may change in the future>.  Do not use constants
217 with multiple values in scalar context.
218
219 B<NOTE:> This implies that the expression defining the value of a
220 constant is evaluated in list context.  This may produce surprises:
221
222     use constant TIMESTAMP => localtime;                # WRONG!
223     use constant TIMESTAMP => scalar localtime;         # right
224
225 The first line above defines C<TIMESTAMP> as a 9-element list, as
226 returned by localtime() in list context.  To set it to the string
227 returned by localtime() in scalar context, an explicit C<scalar>
228 keyword is required.
229
230 List constants are lists, not arrays.  To index or slice them, they
231 must be placed in parentheses.
232
233     my @workdays = WEEKDAYS[1 .. 5];            # WRONG!
234     my @workdays = (WEEKDAYS)[1 .. 5];          # right
235
236 =head2 Defining multiple constants at once
237
238 Instead of writing multiple C<use constant> statements, you may define
239 multiple constants in a single statement by giving, instead of the
240 constant name, a reference to a hash where the keys are the names of
241 the constants to be defined.  Obviously, all constants defined using
242 this method must have a single value.
243
244     use constant {
245         FOO => "A single value",
246         BAR => "This", "won't", "work!",        # Error!
247     };
248
249 This is a fundamental limitation of the way hashes are constructed in
250 Perl.  The error messages produced when this happens will often be
251 quite cryptic -- in the worst case there may be none at all, and
252 you'll only later find that something is broken.
253
254 When defining multiple constants, you cannot use the values of other
255 constants defined in the same declaration.  This is because the
256 calling package doesn't know about any constant within that group
257 until I<after> the C<use> statement is finished.
258
259     use constant {
260         BITMASK => 0xAFBAEBA8,
261         NEGMASK => ~BITMASK,                    # Error!
262     };
263
264 =head2 Magic constants
265
266 Magical values and references can be made into constants at compile
267 time, allowing for way cool stuff like this.  (These error numbers
268 aren't totally portable, alas.)
269
270     use constant E2BIG => ($! = 7);
271     print   E2BIG, "\n";        # something like "Arg list too long"
272     print 0+E2BIG, "\n";        # "7"
273
274 You can't produce a tied constant by giving a tied scalar as the
275 value.  References to tied variables, however, can be used as
276 constants without any problems.
277
278 =head1 TECHNICAL NOTES
279
280 In the current implementation, scalar constants are actually
281 inlinable subroutines. As of version 5.004 of Perl, the appropriate
282 scalar constant is inserted directly in place of some subroutine
283 calls, thereby saving the overhead of a subroutine call. See
284 L<perlsub/"Constant Functions"> for details about how and when this
285 happens.
286
287 In the rare case in which you need to discover at run time whether a
288 particular constant has been declared via this module, you may use
289 this function to examine the hash C<%constant::declared>. If the given
290 constant name does not include a package name, the current package is
291 used.
292
293     sub declared ($) {
294         use constant 1.01;              # don't omit this!
295         my $name = shift;
296         $name =~ s/^::/main::/;
297         my $pkg = caller;
298         my $full_name = $name =~ /::/ ? $name : "${pkg}::$name";
299         $constant::declared{$full_name};
300     }
301
302 =head1 BUGS
303
304 In the current version of Perl, list constants are not inlined
305 and some symbols may be redefined without generating a warning.
306
307 It is not possible to have a subroutine or a keyword with the same
308 name as a constant in the same package. This is probably a Good Thing.
309
310 A constant with a name in the list C<STDIN STDOUT STDERR ARGV ARGVOUT
311 ENV INC SIG> is not allowed anywhere but in package C<main::>, for
312 technical reasons. 
313
314 Unlike constants in some languages, these cannot be overridden
315 on the command line or via environment variables.
316
317 You can get into trouble if you use constants in a context which
318 automatically quotes barewords (as is true for any subroutine call).
319 For example, you can't say C<$hash{CONSTANT}> because C<CONSTANT> will
320 be interpreted as a string.  Use C<$hash{CONSTANT()}> or
321 C<$hash{+CONSTANT}> to prevent the bareword quoting mechanism from
322 kicking in.  Similarly, since the C<< => >> operator quotes a bareword
323 immediately to its left, you have to say C<< CONSTANT() => 'value' >>
324 (or simply use a comma in place of the big arrow) instead of
325 C<< CONSTANT => 'value' >>.
326
327 =head1 AUTHOR
328
329 Tom Phoenix, E<lt>F<rootbeer@redcat.com>E<gt>, with help from
330 many other folks.
331
332 Multiple constant declarations at once added by Casey West,
333 E<lt>F<casey@geeknest.com>E<gt>.
334
335 Documentation mostly rewritten by Ilmari Karonen,
336 E<lt>F<perl@itz.pp.sci.fi>E<gt>.
337
338 =head1 COPYRIGHT
339
340 Copyright (C) 1997, 1999 Tom Phoenix
341
342 This module is free software; you can redistribute it or modify it
343 under the same terms as Perl itself.
344
345 =cut