Just to expand on what Laurent_R and Anonymonk have said, I would say the OPed question has less to do with the peculiarities of state variables than with the fecund peculiarities of references.

From the OP:
my $cfg = { x => "cat"};

cfg_cache($cfg);

When these two statements from the OPed code finish execution, there are two references to the underlying  { x => "cat" } anonymous hash object: one in the  $cfg lexical variable in the main-line code, another in the  $cfg state variable in the scope of the  cfg_cache() function. The underlying object may be accessed and changed via either reference.

The contents of the config hash being referred to can still be freely manipulated by anyone holding a reference to the original hash (that's what you're seeing when your code prints "mouse") or anyone calling cfg_cache().

This point deserves to be emphasized. The intent of the practice exemplified in the OPed code may be to achieve some kind of immutable data structure, but that's not the case. This can be seen from case E of the example below in which the original hash object is altered using the equivalent of cfg_cache().

c:\@Work\Perl\monks>perl -wMstrict -le "use feature 'state'; ;; my $hashref = { x => 'cat' }; S($hashref); ;; print 'A1: ', S('trash')->{x}; print 'A2: ', $hashref->{x}; ;; $hashref->{x} = 'mouse'; print 'B1: ', S('junk')->{x}; print 'B2: ', $hashref->{x}; ;; undef $hashref; print 'C1: ', S('dreck')->{x}; print 'C2: ', $hashref->{x}; ;; $hashref = { x => 'snark' }; print 'D1: ', S('bilge')->{x}; print 'D2: ', $hashref->{x}; ;; S('cruft')->{x} = 'oliphaunt'; print 'E1: ', S('fudge')->{x}; print 'E2: ', $hashref->{x}; ;; sub S { state $ref = shift; return $ref; } " A1: cat A2: cat B1: mouse B2: mouse C1: mouse Use of uninitialized value in print at -e line 1. C2: D1: mouse D2: snark E1: oliphaunt E2: snark
Is this good practice?

It's always good practice to understand references if you use them. :)


In reply to Re^2: caching hashrefs in state by AnomalousMonk
in thread caching hashrefs in state by agname

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.