Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a succinct list of all perl stateful operators and modifiers?

Tags:

perl

Details for the stateful behaviour for operators such as match (ie. m//g), stat (ie. stat _) and range (ie. //..//) are in the documentation. However is there a 'listing' of all operators or functions that exhibit stateful behaviour? The ones that come to mind are:

#ARGV/File/dir/glob: The current line/position is remembered 
say while <>;    #Read line by line by Line from ARGV files
say while <$fh>; #Read line by line by line from file handle
say while defined($_ = readdir($dh)); #Read an entry at a time from dir handle
say while <*>;   #Read an entry at a time from file glob in current dir
say while <{a,b,c},{1,2}>; #Print combination glob one at a time ie (a1,b1,c1,a2,b2,c2)

#Regex: Global modifier/list context remembers previous matches
say while m/$re/g;       #Print matches one at a time
my $_="hello"; say /hello/g; say /hello/gc;    #Only prints hello once. Stateful continuation from last match position


#stat
stat _;     #Returns stat array state from previous stat "filename";

#range: State remembers if the first condition is met
perl -n -e 'print if 1..10' myfile.txt;  #Bistable flipflop state. Print lines 1 to 10
perl -n -e 'print if /startmatch/../endmatch/' myfile.text; #print lines between matches

#state variable: make your own
sub { state $myStateVar;};    #Your own state variable


Any info would be great. Thanks
like image 353
drclaw Avatar asked Dec 31 '22 17:12

drclaw


1 Answers

There are three stateful operators.

  • glob in scalar context (including <> used as glob).

    for my $pass (1..2) {
       say glob("abc") // "[undef]";
    }
    

    Output

    abc
    [undef]
    
  • The flip-flop operator (.. and ... in scalar context).

    for my $pass (1..2) {
       $. = 5;
       say scalar(5..6);
    }
    

    Output

    1
    2
    
  • state

    for my $pass (1..2) {
       state $x = "abc";
       say $x;
       $x = "def";
    }
    

    Output

    abc
    def
    
  • A lot of operators use the TARG mechanism which makes them technically stateful, but this is an optimization that's transparent to the user. The mechanism allows operators to remember the scalar they return so it can be reused by subsequent invocations.

    perl -e'
       use Devel::Peek qw( Dump );
       for my $pass (1..2) {
          my $x = "abc";
          Dump(uc($x));
       }
    ' 2>&1 | grep -P '^SV ='
    

    Output

    SV = PV(0x55d87231fea0) at 0x55d87237ce08
    SV = PV(0x55d87231fea0) at 0x55d87237ce08
    

    It's not a coincidence that both scalars are at the same address (0x55d87237ce08); it's the same scalar.


  • It was suggested that m//g in scalar context is stateful, but its result is strictly based on its inputs. The effect observed is the result of using pos($_), where $_ is an input.

    local $_ = "abcdef";
    for my $pass (1..2) {
       pos($_) = 2;
       last if !/./g;
       say $&;
    }
    

    Output

    c
    c
    
  • It was suggested that each is stateful, but its result is strictly based on its input. The effect observed is the result of using an iterator that's part of the input.

    my %h = ( a=>1, b=>2, c=>3 );
    for my $pass (1..2) {
       keys(%h);  # `keys` in void context resets a hash's iterator.
       say join " ", each(%h);
    }
    

    Output

    c 3
    c 3
    

    keys and values also use this same iterator.

  • It was suggested that readline and readdir are stateful, but their result is strictly based on their input. The only reason you were getting different outputs is that the input (the file handle or directory handle) was different each time.

These functions (and many others) have side effects, and these side-effects including modifying their inputs. But I wouldn't call them stateful as there are significant differences between these and stateful operators.


  • It was suggested that stat is stateful, but its result is strictly based on its input (be it _ or something else).

This one is not the least bit stateful.

like image 64
ikegami Avatar answered May 19 '23 08:05

ikegami