【问题标题】:Perl: what's the meaning of .=~Perl:.=~ 是什么意思
【发布时间】:2015-04-25 16:32:28
【问题描述】:

在 perl 脚本中,我偶尔会写

my $s = "text";
$s .=~ " another text";
print "$s\n";

没有打印出预期的结果text another text,而是在我的终端中显示了textߞ������ߋ��� 的奇怪文本。

毫无疑问:错误是运营商.=~ 而实际上,我想写.=

但我很好奇:为什么.=~ 不是语法错误?这个操作是什么意思?

【问题讨论】:

    标签: perl operators operator-precedence


    【解决方案1】:

    .=~ 是两个运算符,.=~。波浪号是二元否定运算符,请参阅perlop

    验证:

    $ perl -MO=Deparse,-p -e '$x .=~ $y'
    ($x .= (~$y));
    -e syntax OK
    

    【讨论】:

    • 有趣。这里的优先级是什么?因为=~也用到了
    • @fedorqui:查看文档顶部的优先级表。
    • 不确定。我将left =~ !~ 视为第6 个优先级,而. 出现在第8 个项目符号中。
    • @fedorqui: ~ 排在他们前面(第 5 位)。
    • 不是由优先级决定的。只有当您知道自己拥有什么令牌时,优先级才会发挥作用。标记器总是会找到最大的标记,否则它将永远无法工作。因此,当它找到.,并看到它后面跟着=,它返回.= 运算符。
    【解决方案2】:

    当 Perl 做一些你不理解语法的事情时,你要么 B::Deparse 要么 B::Concise 来弄清楚。

    B::Deparse

    跑步

    $ perl -MO=Deparse
    

    在该代码上产生:

    my $s = 'text';
    $s .= "\337\236\221\220\213\227\232\215\337\213\232\207\213";
    print "$s\n";
    

    B::简洁

    跑步

    $ perl -MO=Concise,-exec 
    

    在该代码上产生:

    1  <0> enter 
    2  <;> nextstate(main 1 -:1) v:{
    3  <$> const[PV "text"] s
    4  <0> padsv[$s:1,2] sRM*/LVINTRO
    5  <2> sassign vKS/2
    6  <;> nextstate(main 2 -:2) v:{
    7  <0> padsv[$s:1,2] sRM
    8  <$> const[PV "\337\236\221\220\213\227\232\215\337\213\232\207\213"] s
    9  <2> concat[t3] vKS/2
    a  <;> nextstate(main 2 -:3) v:{
    b  <0> pushmark s
    c  <0> padsv[$s:1,2] s
    d  <$> const[PV "\n"] s
    e  <2> concat[t4] sK/2
    f  <@> print vK
    g  <@> leave[1 ref] vKP/REFC
    

    在这两种情况下,答案都是一样的。你有一个字面上充满了一堆怪异的字符。这是编译器在编译时将一元按位否定 ~ 应用于文字并将结果存储在解析树中的结果。

    【讨论】:

      【解决方案3】:

      当 choroba 不在时 ;) 您可以使用 B::Deparseppi_dumper 告诉您正在处理什么(.=~

      $ perl -MO=Deparse,-p -e " $foo .=~ /bar/; "
      ($foo .= (~/bar/));
      -e syntax OK
      
      
      $ ppi_dumper foo.pl
      PPI::Document
        PPI::Statement
          PPI::Token::Symbol          '$foo'
          PPI::Token::Whitespace      ' '
          PPI::Token::Operator        '.='
          PPI::Token::Operator        '~'
          PPI::Token::Whitespace      ' '
          PPI::Token::Regexp::Match   '/bar/'
          PPI::Token::Structure       ';'
      

      【讨论】:

      • 他在附近并推荐相同的。我从来没有听说过B::Deparse,所以你的回答会带来有价值的消息 - 谢谢
      猜你喜欢
      • 2018-03-05
      • 2020-05-21
      • 2010-12-28
      • 1970-01-01
      • 2023-03-25
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      相关资源
      最近更新 更多