我怎么能知道这个哈希是否有奇数个元素?
my %hash = ( 1, 2, 3, 4, 5 );
好的,我应该写更多信息。
sub routine {
my ( $first, $hash_ref ) = @_;
if ( $hash_ref refers to a hash with odd numbers of elements ) {
"Second argument refers to a hash with odd numbers of elements.\nFalling back to default values";
$hash_ref = { option1 => 'office', option2 => 34, option3 => 'fast' };
}
...
...
}
routine( [ 'one', 'two', 'three' ], { option1 =>, option2 => undef, option3 => 'fast' );
答案 0 :(得分:7)
好吧,我认为在这个问题中存在一些应该澄清的术语混淆。
Perl 中的哈希总是具有相同数量的键和值 - 因为它基本上是通过键存储某些值的引擎。我的意思是,键值对应该被视为这里的单个元素。 )
但我猜这不是真正的问题。我想OP试图从列表中构建一个哈希值(不是一个数组 - 差别很小,但它仍然存在),并得到了警告。
因此,重点是检查列表中将分配给哈希的元素数量。它可以像......一样简单。
my @list = ( ... there goes a list ... );
print @list % 2; # 1 if the list had an odd number of elements, 0 otherwise
请注意%
运算符在列表变量上强制使用标量上下文:它简单而优雅。 )
更新如我所见,问题略有不同。好吧,让我们谈谈给出的例子,简化一下。
my $anhash = {
option1 =>,
option2 => undef,
option3 => 'fast'
};
看,=>
只是一种语法糖;这项任务可以很容易地重写为......
my $anhash = {
'option1', , 'option2', undef, 'option3', 'fast'
};
关键是第一个逗号和undef
之后的缺失值不一样,因为列表(任何列表)在Perl中自动展平。 undef
可以是任何列表的普通元素,但只会忽略空格。
请注意,在调用过程之前,如果调用过程中包含无效的散列,则会关注您关注的警告(如果设置了use warnings
)引发。因此,任何引起这种情况的人都应该自己处理它,看看他自己的代码:他们说,早点失败。 )
您想使用命名参数,但为缺少的参数设置一些默认值?使用这种技术:
sub test_sub {
my ($args_ref) = @_;
my $default_args_ref = {
option1 => 'xxx',
option2 => 'yyy',
};
$args_ref = { %$default_args_ref, %$args_ref, };
}
然后你的test_sub可能就像这样调用......
test_sub { option1 => 'zzz' };
......甚至......
test_sub {};
答案 1 :(得分:6)
简单的答案是:你得到一个警告:
Odd number of elements in hash assignment at...
假设你没有愚蠢并且发出警告。
硬答案是,一旦完成对散列的分配(并发出警告),它就不再是奇怪了。所以你不能。
my %hash = (1,2,3,4,5);
use Data::Dumper;
print Dumper \%hash;
$VAR1 = {
'1' => 2,
'3' => 4,
'5' => undef
};
如您所见,undef
已插入空白处。现在,您可以检查未定义的值,并假装任何现有的未定义值构成散列中的奇数个元素。但是,如果未定义的值是哈希值中的有效值,则表示您遇到了麻烦。
perl -lwe '
sub isodd { my $count = @_ = grep defined, @_; return ($count % 2) };
%a=(a=>1,2);
print isodd(%a);'
Odd number of elements in hash assignment at -e line 1.
1
在这个单行中,函数isodd
对已定义的参数进行计数,并返回参数的数量是否为奇数。但正如你所看到的,它仍然会发出警告。
答案 2 :(得分:3)
当哈希分配不正确时,您可以使用__WARN__
信号“陷阱”。
use strict ;
use warnings ;
my $odd_hash_length = 0 ;
{
local $SIG{__WARN__} = sub {
my $msg = shift ;
if ($msg =~ m{Odd number of elements in hash assignment at}) {
$odd_hash_length = 1 ;
}
} ;
my %hash = (1, 2, 3, 4, 5) ;
}
# Now do what you want based on $odd_hash_length
if ($odd_hash_length) {
die "the hash had an odd hash length assignment...aborting\n" ;
} else {
print "the hash was initialized correctly\n";
}