連想配列を使った悪い例
前回の続き。
「ハッシュのランダム化」に関係なくダメなコードの例。
※以降の実行結果は、すべてPerl v5.18.1によるものです。
こういうのダメ、絶対。
use strict;
use warnings;
use v5.10;
use Test::More;
my %h = ( a => 'foo', b => 'bar' );
my $exp = join ',' , %h;
is join(',', %h), $exp, 'compare hash.';
for (1..5) {
my %tmp = %h;
is join(',', %tmp), $exp, 'compare hash.';
}
done_testing;
これを10回くらい実行すると、1回くらいこうなる。
$ perl aaa.pl
ok 1 - compare hash.
ok 2 - compare hash.
ok 3 - compare hash.
ok 4 - compare hash.
ok 5 - compare hash.
ok 6 - compare hash.
1..6
けど、十中八九こうなる。
$ perl aaa.pl
ok 1 - compare hash.
not ok 2 - compare hash.
# Failed test 'compare hash.'
# at aaa.pl line 14.
# got: 'a,foo,b,bar'
# expected: 'b,bar,a,foo'
not ok 3 - compare hash.
# Failed test 'compare hash.'
# at aaa.pl line 14.
# got: 'a,foo,b,bar'
# expected: 'b,bar,a,foo'
ok 4 - compare hash.
not ok 5 - compare hash.
# Failed test 'compare hash.'
# at aaa.pl line 14.
# got: 'a,foo,b,bar'
# expected: 'b,bar,a,foo'
ok 6 - compare hash.
1..6
同じ連想配列をjoinでつなげる分には一致するが、
代入の度に順番が変わるので、うまくいかない。
というか、こういう比較方法は悪い例で、
せめて、keysを使って各要素を比較すべき。
たとえば、こんな感じに。
use strict;
use warnings;
use v5.10;
use Test::More;
my %exp = ( a => 'foo', b => 'bar' );
for ( 1..5 ) {
my %got = %exp;
foreach ( keys %exp ) {
is $got{$_}, $exp{$_}, 'compare hash.';
}
}
わざと、何回も代入と比較してるけど、1回で十分。
あと、Test::Moreにはこういう関数もある。
use strict; use warnings; use v5.10; use Test::More; my %exp = ( a => 'foo', b => 'bar' ); my %got = %exp; is_deeply \%got, \%exp, 'compare hash.'; my %wrong = ( a => 'foo', b => 'hoge' ); is_deeply \%wrong, \%exp, 'compare hash.'; done_testing;
実行結果はこんな感じ。
$ perl ccc.pl
ok 1 - compare hash.
not ok 2 - compare hash.
# Failed test 'compare hash.'
# at ccc.pl line 13.
# Structures begin differing at:
# $got->{b} = 'hoge'
# $expected->{b} = 'bar'
1..2
# Looks like you failed 1 test of 2.
おしまい。
Leave a Comment