Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
perl检查嵌套哈希引用_Perl_Key_Defined_Hashref_Autovivification - Fatal编程技术网

perl检查嵌套哈希引用

perl检查嵌套哈希引用,perl,key,defined,hashref,autovivification,Perl,Key,Defined,Hashref,Autovivification,我有以下代码: #!/usr/bin/perl use warnings; use strict; use Data::Dumper; my $site = "test.com"; my $data = { "test" => 1 }; my $user = defined($data->{addons}->{$site}->{username}) ? $data->{addons}->{$site

我有以下代码:

#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;

my $site = "test.com";
my $data = {
        "test" => 1
};

my $user = defined($data->{addons}->{$site}->{username}) ? $data->{addons}->{$site}->{username} : "nothing";

print Dumper($data);
结果是:

$VAR1 = {
          'test' => 1,
          'addons' => {
                        'test.com' => {}
                      }
        };
正如您所看到的,检查用户是否在嵌套结构中定义实际上创建了一个空键。我的任务是如何在不定义键的情况下检查hashref。

您在“自动激活”上遇到了麻烦。Perl会自动在您试图访问的数据结构中创建中间级别。你可以在这里看到它的作用:

$ perl -MData::Dumper -E'if (!$foo->{bar}->{baz}){}; say Dumper $foo'
$VAR1 = {
          'bar' => {}
        };
为了检查
$foo->{bar}->{baz}
是否为真,Perl创建了
$foo->{bar}
。这使得创建复杂的数据结构变得容易,但在查询时可能会出现问题

但看看这个:

$ perl -M-autovivification -MData::Dumper -E'if (!$foo->{bar}->{baz}){}; say Dumper $foo'
$VAR1 = undef;
pragma使得在部分代码中关闭自动激活变得很容易。因此,只需添加:

no autovivification;
在导致问题的代码块中

更新:还有手动方法,包括检查数据结构的每个级别,并在发现与您要查找的内容不匹配时立即停止查找:

$ perl -MData::Dumper -E'if ("HASH" eq ref $foo and exists $foo->{bar} and !$foo->{bar}->{baz}){}; say Dumper $foo'
$VAR1 = undef;
正如所指出的,这是一个错误。通常情况下,您不需要担心它,除非您在某个时候基于此散列键的存在做出假设,或者如果您的数据集太大以至于需要非常仔细的内存管理

您可以使用
no autovification
pragma,最好在有限的词法范围内使用,例如:

my $user;
{  # no autovivification is limited to this block
    no autovivification;
    $user = $data->{addon}{$site}{username} // "nothing";
}
/
是,在本例中使用方便

但对于这样一个简单的问题,您可能会得到一个更简单的解决方案:

my $user;
if ( defined $data->{addon}{$site} ) {
    $user = $data->{addon}{$site}{username} // "nothing";
}

请注意,在第一次使用后,哈希中的箭头运算符是可选的,即可以编写
$foo->{bar}->{baz}
,这在某种程度上更易于阅读。关闭autovivification以避免非问题的内容可能会导致实际问题。@TLP默认情况下,在某些情况下,只有在可能不受欢迎的情况下才能关闭自生功能。你不喜欢遇到问题。别忘了它是词汇范围的,所以如果你担心的话,你只能在需要的地方使用它。