是否可以安全地访问嵌套数据结构中的数据,如Template Toolkit?

时间:2010-06-17 00:15:36

标签: perl

在访问深层嵌套的数据结构时,是否存在提供Template Toolkit等功能的模块?我想提取像$a = $hash{first}[0]{second}{third}[3]这样的东西,而不必测试结构的每个部分,看它是否符合我的期望。如果%hash = {}我想要$a = undef,则不会产生错误。

4 个答案:

答案 0 :(得分:2)

Perl将完全按照您的描述进行

此功能称为自动修复。这意味着容器对象一旦使用就会弹出。只要您没有违反自己设定的任何先例,这就成立了。

例如,当您已将某些内容用作数组引用时尝试将其取消引用是一个错误。更一般地说,如果定义了值,则只有在包含对该类型的引用时,才能将其解除引用为特定类型。

如果您还希望防止滥用,可以将嵌套查找包装在eval块中:

my $x = eval{ $hash{first}[0]{second}{third}[3] };

如果undef失败,则会返回eval。请注意,这不是字符串eval,将写为eval '....';。在块形式中,Perl的eval与其他语言中的try {...}构造类似。

要确定eval是否失败或该位置的值是否确实为undef,请测试特殊变量$@是否为真。如果是,则eval失败,原因将在$@。那将写成:

my $x = eval{ $hash{first}[0]{second}{third}[3] };

if (!$x and $@) { die "nested dereference failed: $@" }

或者你可以使用模块Try::Tiny来抽象实现细节并防止一些边缘情况:

use Try::Tiny;

my $x;
try {
    $x = $hash{first}[0]{second}{third}[3];
} catch {
    die "nested dereference failed: $_";
};

答案 1 :(得分:1)

您的错误可能来自错误的间接级别,而不是因为您没有值。 请注意,您的哈希变量是哈希的标量引用,而不是哈希。因此,它应定义为$hash = {},而不是%hash = {}。然后,您可以在那里访问元素$ hash-> {first},而不是$ hash {first}。等等。如果您正确定义哈希并尝试使用$hash->{first}->[0]->{second}->{third}->[3]之类的内容,那么您将获得完全undef,如您所愿,没有错误。

注意:始终use strict

答案 2 :(得分:1)

查看Data::Diver

您可以通过键名访问任意嵌套结构(如果图层是散列或数组,则无关紧要)。如果有错误,Dive()子例程将返回一个空列表,否则它将返回匹配值。

use strict;
use warnings;

use Data::Diver qw( Dive );

my $a = Dive( \%hash, 'first', 0, 'second', 'third', 3 );

if( defined $a ) {
    print "Got '$a'.\n";
}
else {
    print "Got no match.\n";
}

答案 3 :(得分:0)

这样的东西?

use strict;
use warnings;

my %hash;
my $elem = _eval( '$hash{first}[0]{second}{third}[3]' );

sub _eval {return (eval shift) // undef}

当然你也可以这样做:

my $elem = eval {$hash{first}[0]{second}{third}[3] // undef};