X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2Fconstant.pm;h=906b7770d28fb1e3b0dd8d9099fa4cb5f1d097b6;hb=47a7661deb880b9c5c3ea4517c4908096fdff41f;hp=0a866aa0acc011dbb4ccb6ff38d8695d2eb93634;hpb=39a108ce50cdda5b6c5584d8056cebaacd441121;p=p5sagit%2Fp5-mst-13.2.git diff --git a/lib/constant.pm b/lib/constant.pm index 0a866aa..906b777 100644 --- a/lib/constant.pm +++ b/lib/constant.pm @@ -1,16 +1,16 @@ package constant; - +use 5.005; use strict; -use 5.006_00; use warnings::register; -our($VERSION, %declared); -$VERSION = '1.06'; +use vars qw($VERSION %declared); +$VERSION = '1.17'; #======================================================================= # Some names are evil choices. my %keywords = map +($_, 1), qw{ BEGIN INIT CHECK END DESTROY AUTOLOAD }; +$keywords{UNITCHECK}++ if $] > 5.009; my %forced_into_main = map +($_, 1), qw{ STDIN STDOUT STDERR ARGV ARGVOUT ENV INC SIG }; @@ -31,6 +31,13 @@ sub import { my $constants; my $multiple = ref $_[0]; my $pkg = caller; + my $symtab; + my $str_end = $] >= 5.006 ? "\\z" : "\\Z"; + + if ($] > 5.009002) { + no strict 'refs'; + $symtab = \%{$pkg . '::'}; + }; if ( $multiple ) { if (ref $_[0] ne 'HASH') { @@ -49,7 +56,7 @@ sub import { } # Normal constant name - if ($name =~ /^_?[^\W_0-9]\w*\z/ and !$forbidden{$name}) { + if ($name =~ /^_?[^\W_0-9]\w*$str_end/ and !$forbidden{$name}) { # Everything is okay # Name forced into main, but we're not in main. Fatal. @@ -63,7 +70,7 @@ sub import { Carp::croak("Constant name '$name' begins with '__'"); # Maybe the name is tolerable - } elsif ($name =~ /^[A-Za-z_]\w*\z/) { + } elsif ($name =~ /^[A-Za-z_]\w*$str_end/) { # Then we'll warn only if you've asked for warnings if (warnings::enabled()) { if ($keywords{$name}) { @@ -76,7 +83,7 @@ sub import { # Looks like a boolean # use constant FRED == fred; - } elsif ($name =~ /^[01]?\z/) { + } elsif ($name =~ /^[01]?$str_end/) { require Carp; if (@_) { Carp::croak("Constant name '$name' is invalid"); @@ -94,19 +101,24 @@ sub import { no strict 'refs'; my $full_name = "${pkg}::$name"; $declared{$full_name}++; - if ($multiple) { - my $scalar = $constants->{$name}; - *$full_name = sub () { $scalar }; - } else { - if (@_ == 1) { - my $scalar = $_[0]; - *$full_name = sub () { $scalar }; - } elsif (@_) { - my @list = @_; - *$full_name = sub () { @list }; + if ($multiple || @_ == 1) { + my $scalar = $multiple ? $constants->{$name} : $_[0]; + if ($symtab && !exists $symtab->{$name}) { + # No typeglob yet, so we can use a reference as space- + # efficient proxy for a constant subroutine + # The check in Perl_ck_rvconst knows that inlinable + # constants from cv_const_sv are read only. So we have to: + Internals::SvREADONLY($scalar, 1); + $symtab->{$name} = \$scalar; + mro::method_changed_in($pkg); } else { - *$full_name = sub () { }; + *$full_name = sub () { $scalar }; } + } elsif (@_) { + my @list = @_; + *$full_name = sub () { @list }; + } else { + *$full_name = sub () { }; } } } @@ -147,7 +159,7 @@ constant - Perl pragma to declare constants =head1 DESCRIPTION -This will declare a symbol to be a constant with the given value. +This pragma allows you to declare constants at compile-time. When you declare a constant such as C using the method shown above, each machine your script runs upon can have as many digits @@ -156,7 +168,7 @@ read, more likely to be maintained (and maintained correctly), and far less likely to send a space probe to the wrong planet because nobody noticed the one equation in which you wrote C<3.14195>. -When a constant is used in an expression, perl replaces it with its +When a constant is used in an expression, Perl replaces it with its value at compile time, and may then optimize the expression further. In particular, any code in an C block will be optimized away if the constant is false. @@ -218,8 +230,8 @@ constant is evaluated in list context. This may produce surprises: use constant TIMESTAMP => scalar localtime; # right The first line above defines C as a 9-element list, as -returned by localtime() in list context. To set it to the string -returned by localtime() in scalar context, an explicit C +returned by C in list context. To set it to the string +returned by C in scalar context, an explicit C keyword is required. List constants are lists, not arrays. To index or slice them, they @@ -294,7 +306,7 @@ used. $constant::declared{$full_name}; } -=head1 BUGS +=head1 CAVEATS In the current version of Perl, list constants are not inlined and some symbols may be redefined without generating a warning. @@ -319,7 +331,25 @@ immediately to its left, you have to say C<< CONSTANT() => 'value' >> (or simply use a comma in place of the big arrow) instead of C<< CONSTANT => 'value' >>. -=head1 AUTHOR +=head1 SEE ALSO + +L - Facility for creating read-only scalars, arrays, hashes. + +L - Facility for creating read-only variables. Similar to C, +but uses C instead of C. + +L - Make read-only variables via attribute + +L - Perl extension to the C scalar flag + +L - A selection of general-utility hash subroutines (mostly +to lock/unlock keys and values) + +=head1 BUGS + +Please report any bugs or feature requests via the perlbug(1) utility. + +=head1 AUTHORS Tom Phoenix, EFE, with help from many other folks. @@ -330,7 +360,11 @@ EFE. Documentation mostly rewritten by Ilmari Karonen, EFE. -=head1 COPYRIGHT +This program is maintained by the Perl 5 Porters. +The CPAN distribution is maintained by SEbastien Aperghis-Tramoni +EFE. + +=head1 COPYRIGHT & LICENSE Copyright (C) 1997, 1999 Tom Phoenix