Either replace

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

In reply to Re: constant vector (updated x2) by haukex
in thread constant vector by wbirkett

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.