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