use constant D50 => [96.42, 100, 82.49];
with
sub D50 () { [96.42, 100, 82.49] }
because this will do the same thing as constant (it creates an inlineable sub), but the sub will return a new arrayref every time, or do this:
use Readonly;
Readonly::Array my @D50 => (96.42, 100, 82.49);
print $D50[0], "\n";
$D50[0]++;
__END__
96.42
Modification of a read-only value attempted at ...
But I've also had some strange problems with Readonly (Update: link), so my approach nowadays to constants is simpler: make their names uppercase and assume people know this convention. (But I did need some time to get used to this idea, since I do tend to code defensively.)
Update: Sorry, B::Deparse seems to say that I was incorrect and the sub I showed does not seem to get inlined. Will update when I know more. Update 2: So testing seems to show the equivalent code to what constant is doing (with the same problem that the array may be modified!) is this:
BEGIN {
my $x = [96.42, 100, 82.49];
*D50 = sub () { $x };
}
While other forms, such as simply my $x = [96.42, 100, 82.49]; sub D50 () { $x }, don't get inlined. And I believe the reason sub D50 () { [96.42, 100, 82.49] } doesn't get inlined is exactly what I said above: it constructs a new arrayref on each call, thereby it is not constant. I made this mistake because of the equivalence of use constant FOO => "bar"; and sub FOO () { "bar" }. As LanX points out in the reply, my first suggestion will still work, but just not be as fast as an inlined sub. As another possible alternative, note that constant also allows list constants:
use constant D50 => (96.42, 100, 82.49);
Which you then have to access like so: (D50)[0]
Update 3: While it's fairly well known that the output of B::Deparse can be inaccurate, I think it's still noteworthy that it is misleading in this case in particular.
$ perl -MO=Deparse -e 'use constant X=>[1]; print X->[0]++; print X->[
+0]++'
use constant ('X', [1]);
print [1]->[0]++;
print [1]->[0]++;
$ perl -le 'use constant X=>[1]; print X->[0]++; print X->[0]++'
1
2
|