1

$description 是来自格式为 yaml 文件的输入

main_key:
 -
  key1:value2
  key2:value2
 -
  key1:value1
  key2:value2

基本上这是哈希数组的哈希。

我输入 $description 并按如下方式处理内部哈希:

while (  my ( $mod, $defined )  = each %{ $description } ) {
  my $index = 0;
  foreach ( @{ $defined } ) {
    while ( my ( $key, $value )  = each %{ $_ } ) {
         process ( $key, $mod, $description, $index );
    }
  $index = $index + 1;
  }
}

当某些“关键字”用作键时,我替换添加更多键、值对到内部散列函数 1() 和函数 2() 返回一个散列指针。

sub process {
      my ( $key, $mod, $description, $index ) = @_; 
      my $parameters;
      if ( $key eq 'keyword' ) {
             $parameters = function1( );
      }
      else {
             $parameters = function2( );
      }
      $description->{$mod}[$index] = { %$parameters, %{$description->{$mod}[$index]} };
}

这里的问题是主代码中的“while (my ($key, $value) = each %{ $_})”会永远运行,一遍又一遍地使用相同的键和值。

4

2 回答 2

1

是的。不要那样做。

循环遍历哈希时切勿修改哈希。从perldoc -f each

如果您在迭代散列时添加或删除它的元素,条目可能会被跳过或重复——所以不要这样做。

一般模式是建立修改列表,然后在循环结束后进行修改。当然,您可以将该序列嵌入到遍历散列的外部循环中,直到不再需要进行修改。

于 2013-05-10T23:47:55.747 回答
1

您的代码的这种重构工作正常。我已经重写process了最里面的哈希所需的一切。我已经命名了这些$item,因为我不知道它们应该代表什么。请将此修改为更具描述性的内容。

从来没有任何理由传递所有这些参数,因为 , 和 的值$description$mod用于$index定位有问题的哈希,$description->{$mod}[$index]因此它也可以直接作为参考传递,这就是我所做的。此外,因为processnow 循环遍历数组内容,所以也不需要传递$key,所以子程序现在只有一个参数。

的每个元素都$item被检查,为该元素添加的新数据散列是从function1function2酌情获取并推送到@params而不是直接插入。

一旦所有的新值都建立起来,它们都被添加进去$item,这个过程就完成了。

for my $defined (values %$description) {
  process($_) for @$defined;
}

sub process {
  my ($item) = @_;
  my @params;

  for my $key (keys %$item) {
    push @params, $key eq 'keyword' ? function1() : function2();
  }

  for my $params (@params) {
    @{$item}{keys %$params} = values %{$params};
  }
}
于 2013-05-11T00:33:12.767 回答