diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-06-28 01:27:48 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-25 23:48:01 -0700 |
commit | 94d5c1748d4becd9d5dc21c90a0cae02d399076d (patch) | |
tree | 874cd8cb05cc13e86fd2f378cb856111b7bfed1e /dist | |
parent | 82c2360886b2bdf906710e9ba6b5639cece80e9f (diff) | |
download | perl-94d5c1748d4becd9d5dc21c90a0cae02d399076d.tar.gz |
Stop constant.pm from (ab)using subs for scalars
under versions that support $::{foo} = \1.
This changes no behaviour. Future commits will change the way
sub(){42} and sub(){$forty_two} work. (The former will return a muta-
ble value; the latter will not be inlined at all.)
Diffstat (limited to 'dist')
-rw-r--r-- | dist/constant/lib/constant.pm | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/dist/constant/lib/constant.pm b/dist/constant/lib/constant.pm index 035bce2374..dbd1142200 100644 --- a/dist/constant/lib/constant.pm +++ b/dist/constant/lib/constant.pm @@ -25,12 +25,19 @@ 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 }; + if ($const) { + Internals::SvREADONLY($const, 1); + Internals::SvREADONLY($downgrade, 1); + $constant::{_CAN_PCS} = \$const; + $constant::{_DOWNGRADE} = \$downgrade; + } + else { + no strict 'refs'; + *{"_CAN_PCS"} = sub () {$const}; + *{"_DOWNGRADE"} = sub () { $downgrade }; + } } #======================================================================= @@ -128,14 +135,23 @@ 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 }; } |