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'
};

重要なのは、リスト(任意のリスト)がPerlで自動的にフラット化されるため、最初のコンマの後に欠落している値undef が同じではないということです。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 に答える