【问题标题】:How to properly declare hash outside BEGIN block?如何在 BEGIN 块外正确声明散列?
【发布时间】:2012-10-29 21:44:14
【问题描述】:

考虑这个简单的程序。你能解释一下为什么取消前两行的注释后输出不同吗?我的 use strict 哈希发生了什么?如何修复程序以使用use strict

echo -e "key1\nkey2\nkey3" | perl -lne '
  #use strict; use warnings;
  #my %hash;
  BEGIN { 
    $hash{'key3'} = "value";
  }   
  chomp;
  if ($hash{$_}) {
    print "$_ matched";
  } else {
    print "$_ unmatched ";
  }
'

输出:

key1 unmatched 
key2 unmatched 
key3 matched

【问题讨论】:

    标签: perl


    【解决方案1】:

    perl -ln 包装代码以便您最终得到

    BEGIN { $/ = "\n"; $\ = "\n"; }
    LINE: while (<>) {
        chomp;
        use strict; use warnings;
        my %hash;
        BEGIN { $hash{key3} = "value"; }
        ...
    }
    

    注意您如何为每一行创建一个新的%hash?如果你想使用use strict;,你可以使用包变量。

    perl -lne'
        use strict; use warnings;
        our %hash;
        BEGIN { $hash{key3} = "value"; }
        ...
    '
    

    否则,你必须放弃-n

    perl -le'
        use strict; use warnings;
        my %hash = ( key3 => "value" );
        while (<>) {
            chomp;
            ...
        }
    '
    

    PS - 您可能已经注意到,chomp 同时使用 -l-n 时毫无用处。

    【讨论】:

      【解决方案2】:

      使用-n 开关隐式地将您的整个程序放入while (defined($_=&lt;ARGV&gt;)) { ... 块中,包括您的my %hash 语句:

      perl -MO=Deparse -lne '
        use strict; use warnings; my %hash;
        BEGIN {
          $hash{'key3'} = "value";
        }
        chomp;
        if ($hash{$_}) {
          print "$_ matched";
        } else {
          print "$_ unmatched ";
        }
      '
      
      BEGIN { $/ = "\n"; $\ = "\n"; }
      LINE: while (defined($_ = <ARGV>)) {
          chomp $_;
          use warnings;
          use strict 'refs';
          my %hash;
          sub BEGIN {
              $hash{'key3'} = 'value';
          }
          &BEGIN;
          chomp $_;
          if ($hash{$_}) {
              print "$_ matched";
          }
          else {
              print "$_ unmatched ";
          }
      }
      -e syntax OK
      

      也就是说,my %hash 在循环的每次迭代中都会重新声明。要将其保持为单行且不使其过于繁琐,请考虑将 our %hash 声明为使 %hash 成为包变量。

      【讨论】:

      • 已接受 Deparse 技巧的答案。如果我知道这一点,我就不需要问这个问题了。
      猜你喜欢
      • 1970-01-01
      • 2016-01-27
      • 1970-01-01
      • 1970-01-01
      • 2016-08-09
      • 1970-01-01
      • 1970-01-01
      • 2017-12-16
      • 1970-01-01
      相关资源
      最近更新 更多