简体   繁体   English

不能将字符串(“ 1”)用作HASH引用,嵌入式哈希问题

[英]Can't use string (“1”) as a HASH ref, embedded hash issue

Many similar questions have been asked, but mine is quite specific and none of the answers seem to work. 已经提出了许多类似的问题,但我的回答很具体,似乎没有一个答案可行。

The script below is run in a loop (over @keys ). 下面的脚本循环运行(通过@keys )。 I want to check if some pattern is available as a value (second if ). 我想检查某个模式是否可以用作值( if是,则为第二个)。 If it is, get the ending number out of it. 如果是,请从中取出结尾编号。 Then, I want to add a value on the index of that number in an array that does not necessarily exist yet. 然后,我想在一个不一定存在的数组中的该数字的索引上添加一个值。 The example input/output below might clarify things. 下面的示例输入/输出可能会澄清一些问题。

The reference might be a bit complicated, but it is the idea that %ini is a hash, bf in there is a hash, and another one in there eg topattrs . 引用可能有点复杂,但是它的想法是%ini是一个哈希, bf里面有一个哈希,那里还有另一个,例如topattrs Finally, in the next element $v I want to create an array alts if it doesn't exist yet. 最后,在下一个元素$v如果还不存在,我想创建一个数组alts It has to be an array and not a hash because the order of this array matters! 它必须是一个数组,而不是哈希,因为此数组的顺序很重要! Then, I want to add the value of $alt on that index position. 然后,我想在该索引位置上添加$alt的值。

my @keys = keys %{$ini{'bf'}};
foreach (@keys) {
    my $v = $ini{'bf'}{$_};
    if (my ($p, $d) = $_ =~ /(top|sub)attr(\d+)$/) {
        $ini{'bf'}{"${p}attrs"}{$v} = 1;
        delete $ini{'bf'}{$_};

        if (my ($alt) = grep( /${p}attr${d}_alt\d+/, @keys ) ) {
            my ($altd) = $alt =~ /(\d+)$/;
            $ini{'bf'}{"${p}attrs"}{$v}{'alts'}[$altd] = $ini{'bf'}{$alt}; # line 23
        }
    }
}
print Dumper(\%ini);

However, Perl throws me an error: 但是,Perl抛出一个错误:

Can't use string ("1") as a HASH ref while "strict refs" in use at line 23. 在第23行使用“ strict refs”时,不能将字符串(“ 1”)用作HASH ref。

So I guess Perl is interpreting alts as a hash, even though I want to use it as an array so I must be doing something wrong when referencing. 因此,我想Perl会将alts解释为哈希,即使我想将其用作数组,因此在引用时我一定做错了。 Maybe the fact that the array doesn't exist beforehand has to do with it as well? 也许事先不存在数组的事实也与它有关?

Example input: 输入示例:

$VAR1 = {
  'bf' => {
    'subattr2_alt2' => 'pos',
    'subattr2_alt1' => 'pt',
    'topattr1' => 'cat',
    'subattr1' => 'rel',
    'subattr2' => 'cat'
  }
};

Output wanted: 想要的输出:

$VAR1 = {
  'bf' => {
    'topattrs' => {
      'cat' => 1
    },
    'subattrs' => {
      'cat' => ['pt', 'pos'],
      'rel' => 1
    }
  }

You set the $ini{'bf'}{"${p}attrs"}{$v} to 1 and then later on (line 23) try to use the same as a hash. 您将$ini{'bf'}{"${p}attrs"}{$v}为1,然后在第23行上尝试将其用作哈希。

my @keys = keys %{$ini{'bf'}};
foreach (@keys) {
    my $v = $ini{'bf'}{$_};
    if (my ($p, $d) = $_ =~ /(top|sub)attr(\d+)$/) {
        $ini{'bf'}{"${p}attrs"}{$v} = 1;       #### <==== HERE
        delete $ini{'bf'}{$_};

        if (my ($alt) = grep( /${p}attr${d}_alt\d+/, @keys ) ) {
            my ($altd) = $alt =~ /(\d+)$/;
            $ini{'bf'}{"${p}attrs"}{$v}{'alts'}[$altd] = $ini{'bf'}{$alt}; # line 23
        }
    }
}
print Dumper(\%ini);

Change the marked line to 将标记的行更改为

$ini{'bf'}{"${p}attrs"}{$v} = {} ;

or simply remove the line because perl will create needed hashref due to autovivification. 或只是删除该行,因为由于自动生存,perl将创建所需的hashref。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM