source: trunk/third/perl/lib/constant.pm @ 14545

Revision 14545, 8.9 KB checked in by ghudson, 24 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r14544, which included commits to RCS files with non-trunk default branches.
Line 
1package constant;
2
3use strict;
4use 5.005_64;
5use warnings::register;
6
7our($VERSION, %declared);
8$VERSION = '1.02';
9
10#=======================================================================
11
12# Some names are evil choices.
13my %keywords = map +($_, 1), qw{ BEGIN INIT CHECK END DESTROY AUTOLOAD };
14
15my %forced_into_main = map +($_, 1),
16    qw{ STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG };
17
18my %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#=======================================================================
28sub import {
29    my $class = shift;
30    return unless @_;                   # Ignore 'use constant;'
31    my $name = shift;
32    unless (defined $name) {
33        require Carp;
34        Carp::croak("Can't use undef as constant name");
35    }
36    my $pkg = caller;
37
38    # Normal constant name
39    if ($name =~ /^_?[^\W_0-9]\w*\z/ and !$forbidden{$name}) {
40        # Everything is okay
41
42    # Name forced into main, but we're not in main. Fatal.
43    } elsif ($forced_into_main{$name} and $pkg ne 'main') {
44        require Carp;
45        Carp::croak("Constant name '$name' is forced into main::");
46
47    # Starts with double underscore. Fatal.
48    } elsif ($name =~ /^__/) {
49        require Carp;
50        Carp::croak("Constant name '$name' begins with '__'");
51
52    # Maybe the name is tolerable
53    } elsif ($name =~ /^[A-Za-z_]\w*\z/) {
54        # Then we'll warn only if you've asked for warnings
55        if (warnings::enabled()) {
56            if ($keywords{$name}) {
57                warnings::warn("Constant name '$name' is a Perl keyword");
58            } elsif ($forced_into_main{$name}) {
59                warnings::warn("Constant name '$name' is " .
60                    "forced into package main::");
61            } else {
62                # Catch-all - what did I miss? If you get this error,
63                # please let me know what your constant's name was.
64                # Write to <rootbeer@redcat.com>. Thanks!
65                warnings::warn("Constant name '$name' has unknown problems");
66            }
67        }
68
69    # Looks like a boolean
70    #           use constant FRED == fred;
71    } elsif ($name =~ /^[01]?\z/) {
72        require Carp;
73        if (@_) {
74            Carp::croak("Constant name '$name' is invalid");
75        } else {
76            Carp::croak("Constant name looks like boolean value");
77        }
78
79    } else {
80        # Must have bad characters
81        require Carp;
82        Carp::croak("Constant name '$name' has invalid characters");
83    }
84
85    {
86        no strict 'refs';
87        my $full_name = "${pkg}::$name";
88        $declared{$full_name}++;
89        if (@_ == 1) {
90            my $scalar = $_[0];
91            *$full_name = sub () { $scalar };
92        } elsif (@_) {
93            my @list = @_;
94            *$full_name = sub () { @list };
95        } else {
96            *$full_name = sub () { };
97        }
98    }
99
100}
101
1021;
103
104__END__
105
106=head1 NAME
107
108constant - Perl pragma to declare constants
109
110=head1 SYNOPSIS
111
112    use constant BUFFER_SIZE    => 4096;
113    use constant ONE_YEAR       => 365.2425 * 24 * 60 * 60;
114    use constant PI             => 4 * atan2 1, 1;
115    use constant DEBUGGING      => 0;
116    use constant ORACLE         => 'oracle@cs.indiana.edu';
117    use constant USERNAME       => scalar getpwuid($<);
118    use constant USERINFO       => getpwuid($<);
119
120    sub deg2rad { PI * $_[0] / 180 }
121
122    print "This line does nothing"              unless DEBUGGING;
123
124    # references can be constants
125    use constant CHASH          => { foo => 42 };
126    use constant CARRAY         => [ 1,2,3,4 ];
127    use constant CPSEUDOHASH    => [ { foo => 1}, 42 ];
128    use constant CCODE          => sub { "bite $_[0]\n" };
129
130    print CHASH->{foo};
131    print CARRAY->[$i];
132    print CPSEUDOHASH->{foo};
133    print CCODE->("me");
134    print CHASH->[10];                  # compile-time error
135
136=head1 DESCRIPTION
137
138This will declare a symbol to be a constant with the given scalar
139or list value.
140
141When you declare a constant such as C<PI> using the method shown
142above, each machine your script runs upon can have as many digits
143of accuracy as it can use. Also, your program will be easier to
144read, more likely to be maintained (and maintained correctly), and
145far less likely to send a space probe to the wrong planet because
146nobody noticed the one equation in which you wrote C<3.14195>.
147
148=head1 NOTES
149
150The value or values are evaluated in a list context. You may override
151this with C<scalar> as shown above.
152
153These constants do not directly interpolate into double-quotish
154strings, although you may do so indirectly. (See L<perlref> for
155details about how this works.)
156
157    print "The value of PI is @{[ PI ]}.\n";
158
159List constants are returned as lists, not as arrays.
160
161    $homedir = USERINFO[7];             # WRONG
162    $homedir = (USERINFO)[7];           # Right
163
164The use of all caps for constant names is merely a convention,
165although it is recommended in order to make constants stand out
166and to help avoid collisions with other barewords, keywords, and
167subroutine names. Constant names must begin with a letter or
168underscore. Names beginning with a double underscore are reserved. Some
169poor choices for names will generate warnings, if warnings are enabled at
170compile time.
171
172Constant symbols are package scoped (rather than block scoped, as
173C<use strict> is). That is, you can refer to a constant from package
174Other as C<Other::CONST>.
175
176As with all C<use> directives, defining a constant happens at
177compile time. Thus, it's probably not correct to put a constant
178declaration inside of a conditional statement (like C<if ($foo)
179{ use constant ... }>).
180
181Omitting the value for a symbol gives it the value of C<undef> in
182a scalar context or the empty list, C<()>, in a list context. This
183isn't so nice as it may sound, though, because in this case you
184must either quote the symbol name, or use a big arrow, (C<=E<gt>>),
185with nothing to point to. It is probably best to declare these
186explicitly.
187
188    use constant UNICORNS       => ();
189    use constant LOGFILE        => undef;
190
191The result from evaluating a list constant in a scalar context is
192not documented, and is B<not> guaranteed to be any particular value
193in the future. In particular, you should not rely upon it being
194the number of elements in the list, especially since it is not
195B<necessarily> that value in the current implementation.
196
197Magical values, tied values, and references can be made into
198constants at compile time, allowing for way cool stuff like this.
199(These error numbers aren't totally portable, alas.)
200
201    use constant E2BIG => ($! = 7);
202    print   E2BIG, "\n";        # something like "Arg list too long"
203    print 0+E2BIG, "\n";        # "7"
204
205Dereferencing constant references incorrectly (such as using an array
206subscript on a constant hash reference, or vice versa) will be trapped at
207compile time.
208
209In the rare case in which you need to discover at run time whether a
210particular constant has been declared via this module, you may use
211this function to examine the hash C<%constant::declared>. If the given
212constant name does not include a package name, the current package is
213used.
214
215    sub declared ($) {
216        use constant 1.01;              # don't omit this!
217        my $name = shift;
218        $name =~ s/^::/main::/;
219        my $pkg = caller;
220        my $full_name = $name =~ /::/ ? $name : "${pkg}::$name";
221        $constant::declared{$full_name};
222    }
223
224=head1 TECHNICAL NOTE
225
226In the current implementation, scalar constants are actually
227inlinable subroutines. As of version 5.004 of Perl, the appropriate
228scalar constant is inserted directly in place of some subroutine
229calls, thereby saving the overhead of a subroutine call. See
230L<perlsub/"Constant Functions"> for details about how and when this
231happens.
232
233=head1 BUGS
234
235In the current version of Perl, list constants are not inlined
236and some symbols may be redefined without generating a warning.
237
238It is not possible to have a subroutine or keyword with the same
239name as a constant in the same package. This is probably a Good Thing.
240
241A constant with a name in the list C<STDIN STDOUT STDERR ARGV ARGVOUT
242ENV INC SIG> is not allowed anywhere but in package C<main::>, for
243technical reasons.
244
245Even though a reference may be declared as a constant, the reference may
246point to data which may be changed, as this code shows.
247
248    use constant CARRAY         => [ 1,2,3,4 ];
249    print CARRAY->[1];
250    CARRAY->[1] = " be changed";
251    print CARRAY->[1];
252
253Unlike constants in some languages, these cannot be overridden
254on the command line or via environment variables.
255
256You can get into trouble if you use constants in a context which
257automatically quotes barewords (as is true for any subroutine call).
258For example, you can't say C<$hash{CONSTANT}> because C<CONSTANT> will
259be interpreted as a string.  Use C<$hash{CONSTANT()}> or
260C<$hash{+CONSTANT}> to prevent the bareword quoting mechanism from
261kicking in.  Similarly, since the C<=E<gt>> operator quotes a bareword
262immediately to its left, you have to say C<CONSTANT() =E<gt> 'value'>
263(or simply use a comma in place of the big arrow) instead of
264C<CONSTANT =E<gt> 'value'>.
265
266=head1 AUTHOR
267
268Tom Phoenix, E<lt>F<rootbeer@redcat.com>E<gt>, with help from
269many other folks.
270
271=head1 COPYRIGHT
272
273Copyright (C) 1997, 1999 Tom Phoenix
274
275This module is free software; you can redistribute it or modify it
276under the same terms as Perl itself.
277
278=cut
Note: See TracBrowser for help on using the repository browser.