是否有所有 perl 有状态运算符和修饰符的简洁列表?

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

有关运算符状态行为的详细信息,例如匹配(即 m//g)、统计(即 stat _)和范围(即 //..//)在文档中.但是,是否存在 'listing' 所有表现出状态行为的运算符或函数?想到的是:

#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

共有三个有状态运算符。

  • glob 在标量上下文中(包括用作 glob<>)。

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

    输出

    abc
    [undef]
    
  • 触发器运算符(标量上下文中的.....)。

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

    输出

    1
    2
    
  • state

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

    输出

    abc
    def
    
  • 很多操作符使用 TARG 机制,这使得它们在技术上是有状态的,但这是一种对用户透明的优化。该机制允许操作员记住他们 return 的标量,以便后续调用可以重用它。

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

    输出

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

    这两个标量在同一地址并非巧合 (0x55d87237ce08);这是相同的标量。


  • 有人建议标量上下文中的 m//g 是有状态的,但其结果严格基于其输入。观察到的效果是使用pos($_)的结果,其中$_是一个输入。

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

    输出

    c
    c
    
  • 有人建议 each 是有状态的,但其结果严格基于其输入。观察到的效果是使用作为输入一部分的迭代器的结果。

    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);
    }
    

    输出

    c 3
    c 3
    

    keysvalues 也使用相同的迭代器。

  • 有人建议 readlinereaddir 是有状态的,但它们的结果严格基于它们的输入。您获得不同输出的唯一原因是每次输入(文件句柄或目录句柄)都不同。

这些函数(以及许多其他函数)有副作用,这些副作用包括修改它们的输入。但我不会称它们为有状态的,因为它们与有状态的运算符之间存在显着差异。


  • 有人建议 stat 是有状态的,但其结果严格基于其输入(无论是 _ 还是其他)。

这个一点都没有状态。

cperl 已将所有非有状态操作标记为纯操作。 这将是 https://github.com/perl11/cperl/blob/master/regen/opcodes

中第三列中的 p

在运行时,您可以使用 PL_opargs[optype] & OA_PURE 检查。 cperl 还支持函数的 :pure 属性,编译器稍后应该自动标记它们,如果对 jit 来说有价值的话。