我正在重新熟悉 Perl,并且刚刚使用 module-starter 来初始化一个新项目。我现在正在尝试理解生成的代码。除了以下指示的行外,一切都很好:

sub not_in_file_ok {
  my ($filename, %regex) = @_;
  open( my $fh, '<', $filename )
    or die "couldn't open $filename for reading: $!";

  my %violated;

  while (my $line = <$fh>) {
    while (my ($desc, $regex) = each %regex) {
        if ($line =~ $regex) {
            ##I'm having problems here
            push @{$violated{$desc}||=[]}, $.;
        }
    }
  }
  ...
}

我有两个问题:
  • ||=[] 。这是 | 后跟 |= ,还是 || 后跟 =[] 。有人可以告诉我这里发生了什么吗? (我猜测“如果哈希为空,则创建一个空的匿名数组来初始化哈希”,但我正在努力了解它是如何从代码中形成的。)
  • push @{$violated{$desc}}, $. 我理解这意味着“将行号分配给哈希 $desc 的键 %violated 。但是从我读到的代码中,“查找 desc 的键 $violated{$desc} 的值($violated{$desc} 部分),然后将此值用作对数组的符号引用(@{$value} 部分),然后将行号推送到该数组上”。我不知道如何协调这两个 View 。

  • 我认为在这行代码中我有很多东西要学习 - 有人可以帮助我完成它吗?

    最佳答案

  • ||= :这是一个赋值运算符。例子
    $a ||= $b;
    # corresponds to
    $a = $a || $b;
    

    man perlop 。在你的例子中
    $a ||= [];
    # corresponds to
    $a = $a || [];
    

    即:如果左操作数定义为空,否则分配一个空数组引用
  • %violated 包含每个值的数组引用。你可以这样看:
    my $array_ref = $violated{$desc};
    push @{array_ref}, $.;
    

  • 写得更详细:
      if (! $violated{$desc} ) {
          $violated{$desc} = [];
      }
      my $array_ref = $violated{$desc};
      push @{ $array_ref }, $.;
    

    编辑

    数组和数组引用
  • 一个用 () 构造的数组,包含一个动态有序的元素列表(在 Perl 数组中可以动态增长)
  • 数组引用是对数组的引用(或多或少是没有指针运算的指针)。您可以使用 []
  • 创建和数组引用

    例子
    my @a = ( 1, 2, 3);
    # $a[0] will contain 1
    
    my $array_ref = [ 10, 11, 12 ];
    # array_ref is a _pointer_ to an array containing 10, 11 and 12
    

    要访问数组引用,您需要取消引用它:
    @{ $array_ref };
    
    my @array = @{ $array_ref }; # is valid
    

    您可以将 { $array_ref} 作为数组访问
    ${ $array_ref }[0]
    

    现在回到您在评论中的问题:%violated 是具有以下键值对的散列:字符串 ($desc) 和数组引用

    10-07 18:56