3

我怎么知道这个哈希是否有奇数个元素?

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' );
4

3 回答 3

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 {};
于 2012-06-16T10:43:08.043 回答
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计算定义的参数并返回参数的数量是否为奇数。但如您所见,它仍然发出警告。

于 2012-06-16T10:38:09.323 回答
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";
}

另请参阅如何在 Perl 中捕获和保存警告

于 2012-06-16T13:13:51.487 回答