連想配列を使った悪い例
前回の続き。
「ハッシュのランダム化」に関係なくダメなコードの例。
※以降の実行結果は、すべて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