http://www.perlmonks.org?node_id=1166856

basiliscos has asked for the wisdom of the Perl Monks concerning the following question:

Hello dear monks,

My colleges too-frequently use state feature for aggressive caching. That makes some test problematic, and the functions to be unpure. I'm asking them do not use state, but it seems my arguments aren't strong enough.

I think I've read some article about state feature misuse, but I can't remember it. If you have a link to some blog, please, share it

PS. May be I'm not right and state isn't so bad?

WBR, basiliscos.

Replies are listed 'Best First'.
Re: state is the root of evil?
by choroba (Cardinal) on Jun 29, 2016 at 13:00 UTC
    The problem I have with state is that I usually don't want the variable to be set only once, but only once for a given part of the data . It behaves this way only in anonymous subs, because you declare a new sub for each iteration. Cf.
    #! /usr/bin/perl use warnings; use strict; use feature 'state'; sub frobnicate { state $f = 0; $f += shift; $f } my @data = ( [ 1, 1, 1 ], [ 1, 2, 3 ], [ 4, 4, 4 ], ); for my $block (@data) { my $block_result = 0; for my $element (@$block) { $block_result = frobnicate($element); } print $block_result, "\n"; } print "Versus\n"; for my $block (@data) { my $frobnicate = sub { state $f = 0; $f += shift; $f }; my $block_result = 0; for my $element (@$block) { $block_result = $frobnicate->($element); } print $block_result, "\n"; }

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: state is the root of evil?
by perlfan (Vicar) on Jun 29, 2016 at 17:31 UTC
    I suppose it could be useful for "aggressive caching" if, you want to control access to this variable inside of the subroutine; but that's not really the point of the state declaration.

    It is useful for creating subroutines that maintain a sense of state; for example you may use it to stop a subroutine at one point (state 0 -> state 1) and on the next call it, it will be able to pick up at state 1 (then maybe return when in state 2). Below is a finite state machine implemented lexically inside of a single subroutine using state, which matches on the regular expression ab(ab)*c.
    use strict; use warnings; use feature 'state'; my $test_string = $ARGV[0] // q{ababababac}; sub transition { my $symbol = shift; state $current = 'start'; # initialize on first call to __SUB__ my $trans = { start => { a => 1, b => 'start', c => 'sink' }, 1 => { a => 1, b => 'start', c => 'final' }, final => { a => 'sink', b => 'sink', c => 'sink' }, }; my $next = ( $trans->{$current}->{$symbol} ) ? $trans->{$current}->{$symbol} : q{sink}; print qq{$current -> $next on "$symbol"\n}; $current = $next; # update stateful var, will be this valu +e on next call to __SUB__ return $current; } my $position; for my $s ( split //, $test_string ) { $position = transition($s); } printf( qq{string "%s" is %s\n}, $test_string, ( $position eq q{final} + ) ? q{ACCEPTED} : q{REJECTED} );
    Output (ACCEPTED):
    $ perl state.pl abababac start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" 1 -> final on "c" string "abababac" is ACCEPTED
    Output (REJECTED):
    perl state.pl abababa start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" 1 -> start on "b" start -> 1 on "a" string "abababa" is REJECTED
    The primary use case I am showing here is that, what would normally need to be global in scope can now be cleanly scoped lexically within the subroutine, transition. Can state be used for caching? Yes, but no more effectively than using a global variable.
Re: state is the root of evil?
by BrowserUk (Patriarch) on Jun 29, 2016 at 09:24 UTC
    May be I'm not right and state isn't so bad?

    It would help if you would describe your objections rather than simply stating aphorisms.

    "makes some test problematic, and the functions to be unpure." is like saying eating meat should be banned because: "It's meat; and it tastes like meat."

    • If your tests are "problematic"; use other tests;

      or describe why testing is problematic.

    • "Unpure" (perhaps you mean 'impure') functions are a fact of life in 90% of programming languages and virtually de rigueur in Perl.

      If you think purity is an unassailable requirement; explain why; and let us disavow you of that naïve notion.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.

      Wow! i just added virtually de rigueur (...nahezu unverzichtbar/unerläßlich?) to my flashcards.

      Some smart alecks might claim that this expression is an linguistic impurity.

      Best regards, Karl (...still learning English at the Monastry)

      P.S.: Too much Denglish? I hope not ;-)

      «The Crux of the Biscuit is the Apostrophe»

        Some smart alecks might claim that this expression is an linguistic impurity.

        Fair enough. Though I might retort:

        1. linguistic: from the french:linguistique.
        2. impurity: from the french:impurité


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
Re: state is the root of evil?
by Anonymous Monk on Jun 29, 2016 at 09:20 UTC

    for aggressive caching

    What arguments do they give for using caching/state, and not testing if its broken?