diff -up constant-1.27/lib/constant.pm.orig constant-1.27/lib/constant.pm --- constant-1.27/lib/constant.pm.orig 2014-09-09 10:42:02.450977378 +0200 +++ constant-1.27/lib/constant.pm 2014-09-09 10:42:25.026227379 +0200 @@ -4,7 +4,7 @@ use strict; use warnings::register; use vars qw($VERSION %declared); -$VERSION = '1.27'; +$VERSION = '1.31'; #======================================================================= @@ -25,12 +25,22 @@ BEGIN { # We'd like to do use constant _CAN_PCS => $] > 5.009002 # but that's a bit tricky before we load the constant module :-) # By doing this, we save 1 run time check for *every* call to import. - no strict 'refs'; my $const = $] > 5.009002; - *_CAN_PCS = sub () {$const}; - my $downgrade = $] < 5.015004; # && $] >= 5.008 - *_DOWNGRADE = sub () { $downgrade }; + my $constarray = exists &_make_const; + if ($const) { + Internals::SvREADONLY($const, 1); + Internals::SvREADONLY($downgrade, 1); + $constant::{_CAN_PCS} = \$const; + $constant::{_DOWNGRADE} = \$downgrade; + $constant::{_CAN_PCS_FOR_ARRAY} = \$constarray; + } + else { + no strict 'refs'; + *{"_CAN_PCS"} = sub () {$const}; + *{"_DOWNGRADE"} = sub () { $downgrade }; + *{"_CAN_PCS_FOR_ARRAY"} = sub () { $constarray }; + } } #======================================================================= @@ -128,20 +138,41 @@ sub import { # The constant serves to optimise this entire block out on # 5.8 and earlier. - if (_CAN_PCS && $symtab && !exists $symtab->{$name}) { - # No typeglob yet, so we can use a reference as space- - # efficient proxy for a constant subroutine + if (_CAN_PCS) { + # Use a reference as a proxy for a constant subroutine. + # If this is not a glob yet, it saves space. If it is + # a glob, we must still create it this way to get the + # right internal flags set, as constants are distinct + # from subroutines created with sub(){...}. # 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; - ++$flush_mro; + if ($symtab && !exists $symtab->{$name}) { + $symtab->{$name} = \$scalar; + ++$flush_mro; + } + else { + local $constant::{_dummy} = \$scalar; + *$full_name = \&{"_dummy"}; + } } else { *$full_name = sub () { $scalar }; } } elsif (@_) { my @list = @_; - *$full_name = sub () { @list }; + if (_CAN_PCS_FOR_ARRAY) { + _make_const($list[$_]) for 0..$#list; + _make_const(@list); + if ($symtab && !exists $symtab->{$name}) { + $symtab->{$name} = \@list; + $flush_mro++; + } + else { + local $constant::{_dummy} = \@list; + *$full_name = \&{"_dummy"}; + } + } + else { *$full_name = sub () { @list }; } } else { *$full_name = sub () { }; } @@ -190,7 +221,7 @@ This pragma allows you to declare consta When you declare a constant such as C using the method shown above, each machine your script runs upon can have as many digits -of accuracy as it can use. Also, your program will be easier to +of accuracy as it can use. Also, your program will be easier to 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>. @@ -203,7 +234,7 @@ away if the constant is false. =head1 NOTES As with all C directives, defining a constant happens at -compile time. Thus, it's probably not correct to put a constant +compile time. Thus, it's probably not correct to put a constant declaration inside of a conditional statement (like C). @@ -236,8 +267,8 @@ their own constants to override those in The use of all caps for constant names is merely a convention, although it is recommended in order to make constants stand out and to help avoid collisions with other barewords, keywords, and -subroutine names. Constant names must begin with a letter or -underscore. Names beginning with a double underscore are reserved. Some +subroutine names. Constant names must begin with a letter or +underscore. Names beginning with a double underscore are reserved. Some poor choices for names will generate warnings, if warnings are enabled at compile time. @@ -312,15 +343,15 @@ constants without any problems. =head1 TECHNICAL NOTES In the current implementation, scalar constants are actually -inlinable subroutines. As of version 5.004 of Perl, the appropriate +inlinable subroutines. As of version 5.004 of Perl, the appropriate scalar constant is inserted directly in place of some subroutine -calls, thereby saving the overhead of a subroutine call. See +calls, thereby saving the overhead of a subroutine call. See L for details about how and when this happens. In the rare case in which you need to discover at run time whether a particular constant has been declared via this module, you may use -this function to examine the hash C<%constant::declared>. If the given +this function to examine the hash C<%constant::declared>. If the given constant name does not include a package name, the current package is used. @@ -335,11 +366,12 @@ used. =head1 CAVEATS -In the current version of Perl, list constants are not inlined -and some symbols may be redefined without generating a warning. +List constants are not inlined unless you are using Perl v5.20 or higher. +In v5.20 or higher, they are still not read-only, but that may change in +future versions. It is not possible to have a subroutine or a keyword with the same -name as a constant in the same package. This is probably a Good Thing. +name as a constant in the same package. This is probably a Good Thing. A constant with a name in the list C is not allowed anywhere but in package C, for