【问题标题】:Perl Hash of Hashes Storing References To Within - Can't use string ("") as a HASH refPerl Hash of Hashes 将引用存储到内部 - 不能使用字符串 ("") 作为 HASH ref
【发布时间】:2013-04-19 21:56:22
【问题描述】:

好吧,我有一个函数可以生成一个哈希树,dumper 打印出来看起来像这样:

$VAR1 = {
  'shaders' => {
    'stock_gui.vert' => '',
    'stock_font.vert' => '',
    'stock_gui.frag' => '',
    'stock_font.frag' => ''
  },
  'textures' => {},
  'fonts' => {
    'DroidSansMono.ttf' => '',
    'small' => {
      'DroidSansMono.ttf' => ''
    }
  }
};

现在我正在尝试 dfs 迭代例如字体子树:

push (@stack, \%{$myHash->{'fonts'}});

然后循环:

my $tmpHash = pop(@stack);

然后是 $tmpHash 的 dumper 显示:

$VAR1 = {
  'DroidSansMono.ttf' => '',
  'small' => {
    'DroidSansMono.ttf' => ''
  }
};

问题在于尝试访问哈希引用的子项。我可以数钥匙并看到孩子们。转储器输出看起来不错。但是尝试做类似的事情:

foreach my $childKey ( keys $tmpHash ){
   my $subChildrenCount = scalar keys(%{$tmpHash->{$childKey}});
}

产生错误:

Can't use string ("") as a HASH ref while "strict refs" in use

我认为这是因为 $tmpHash 是一个哈希引用。我可能只需要在某个地方取消引用它。我已经尝试了很多事情,并且都产生了进一步的问题。任何帮助表示赞赏。

如果我尝试:

 %{$tmpHash->{'small'}}

然后它就可以正常工作了。

更新:

  • 如果字符串包含'.'然后发生此错误。硬编码“小”有效。除非我转义 '.',否则硬编码 'stock_gui.vert' 会失败。但是,如果我转义点,则键不匹配...

【问题讨论】:

  • 你应该看看perlref。看起来你对\` and $hash_ref`感到困惑。
  • 顺便说一句,\%{pop(@stack)} 是一种奇怪的做法 pop(@stack)
  • 我的 perl 生锈了,我不会在那里争论。阅读它。 Pop 很奇怪...... pop(@stack) 本身就可以正常工作。
  • 您不需要通过“\%{xxx}”进行持续引用和取消引用 - 这与您的简单“xxx”相同。
  • %$ref 取消引用哈希,然后\ 创建对它的引用。这就像在做$n-1+1

标签: perl hash strict


【解决方案1】:

正如你自己运行它所看到的,

use strict;
use warnings;

my $tmpHash = {
  'DroidSansMono.ttf' => '',
  'small' => {
    'DroidSansMono.ttf' => ''
  }
};

my $subChildrenCount = scalar keys(%{$tmpHash->{'small'}});

您所说的给出该错误的代码实际上并没有给出该错误。我怀疑你真的在做

my $subChildrenCount = scalar keys(%{$tmpHash->{'DroidSansMono.ttf'}});

您的哈希格式没有多大意义。它将字段名称和实际数据混合为键。

【讨论】:

  • 如果我使用现有代码但对密钥进行硬编码,那么它可以工作。如果我执行 foreach 键循环并尝试将键作为 var 引用,那么它会给出该错误。是的,对于一份奇怪的工作来说,这是一种奇怪的哈希格式。有孩子的哈希是目录,没有孩子的哈希是文件。不需要更多信息。
  • 查看更新。这似乎都是关于'。在密钥字符串中。不幸的是,如果我逃脱了“。”使用一些正则表达式然后该错误消失并且所有迭代都很好,除了 'Foo\.ext' 与键 'Foo.ext' 不匹配。
  • 不,带有句点的键本身没有问题。不要再将代码中的错误归咎于 Perl。
  • 您的常见回复...如果 $myKey 包含字符串“foo.bar”,则会给出无法使用空字符串作为哈希引用的错误。如果 $myKey 包含“foo_bar”,它就完美了。如果我用 sed 转义点,它可以工作,但键不再匹配。我将 "$myKey" 用双引号括起来。
  • 废话。当 $x 是 $x->{$mykey} 中的空字符串时,您会收到该错误,而不是当 $x 或 $mykey 包含 foo.bar 时。
猜你喜欢
  • 2016-01-11
  • 1970-01-01
  • 2016-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-08
  • 1970-01-01
  • 2022-01-15
相关资源
最近更新 更多