summaryrefslogtreecommitdiff
path: root/dist/constant
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-06-29 23:59:48 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-25 23:48:01 -0700
commit15635cbfaf61c4ea7f360fd74037b2f34a1fe3b7 (patch)
treec79e68bdb846911baa009f98b56df00261134151 /dist/constant
parent6f1b3ab07ea077b8191fe508269d778bc64a5f50 (diff)
downloadperl-15635cbfaf61c4ea7f360fd74037b2f34a1fe3b7.tar.gz
constant.pm: Make list constants read-only
Here we take advantage of the array-ref-stash-elem mechanism added in the previous commit, which causes the actual elements of the stored array to be pushed on to the stack.
Diffstat (limited to 'dist/constant')
-rw-r--r--dist/constant/lib/constant.pm17
-rw-r--r--dist/constant/t/constant.t1
2 files changed, 16 insertions, 2 deletions
diff --git a/dist/constant/lib/constant.pm b/dist/constant/lib/constant.pm
index 861d4f0a44..f947117a7a 100644
--- a/dist/constant/lib/constant.pm
+++ b/dist/constant/lib/constant.pm
@@ -27,16 +27,19 @@ BEGIN {
# By doing this, we save 1 run time check for *every* call to import.
my $const = $] > 5.009002;
my $downgrade = $] < 5.015004; # && $] >= 5.008
+ my $constarray = $] > 5.019001;
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 };
}
}
@@ -157,7 +160,19 @@ sub import {
}
} elsif (@_) {
my @list = @_;
- *$full_name = sub () { @list };
+ if (_CAN_PCS_FOR_ARRAY) {
+ Internals::SvREADONLY(@list, 1);
+ Internals::SvREADONLY($list[$_], 1) for 0..$#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 () { };
}
diff --git a/dist/constant/t/constant.t b/dist/constant/t/constant.t
index 93fb5784c8..3a822713ea 100644
--- a/dist/constant/t/constant.t
+++ b/dist/constant/t/constant.t
@@ -396,7 +396,6 @@ SKIP: {
# either, hence the to-do status).
SKIP: {
skip "fails under 5.19.1 and earlier", 2 if $] < 5.019002;
- local $TODO = " ";
use constant constant_list => 1..2;
for (constant_list) {
my $num = $_;