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.
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, 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, 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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.