in reply to Re: caching hashrefs in state
in thread caching hashrefs in state
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. :)
|
|---|