我正在尝试编写一个简单的Perl模块来创建和操作一副牌。 (我知道这些模块已经存在;我正在做它作为练习。)套牌创建很好,并在首次创建后打印正常。但是,如果我洗牌,那么再次打印牌组会产生警告:
Use of uninitialized value in join or string at Deck.pm line 23.
以下是代码,第23行用注释表示:
sub new {
my $classname = shift;
my @suits = ("s", "h", "d", "c");
my @pips = ("A", "K", "Q", "J", reverse 2 .. 10);
my @deck;
foreach my $suit (@suits) {
foreach my $pip (@pips) {
push (@deck, "$pip$suit");
}
}
my $self = \@deck;
bless($self, $classname);
return $self;
}
sub print_deck {
my $self = shift;
print join " ", @{$self}; # This is line 23
print "\n";
}
sub shuffle {
my $self = shift;
my $i = @{$self};
while ($i > 0) {
my $j = int(rand($i));
@{$self}[$i, $j] = @{$self}[$j, $i];
$i--;
}
}
1;
我有一个测试脚本,可以创建一个新的牌组,打印它,将其洗牌,然后重新打印。第一次打印很好,但第二次打印会生成上面显示的警告。这是测试脚本:
my $deck = Deck->new;
print "The deck of cards looks like:\n";
$deck->print_deck; # This print works fine
$deck->shuffle;
print "The shuffled deck looks like:\n";
$deck->print_deck; # This print generates the warning
我做错了什么?谢谢!
答案 0 :(得分:4)
您的shuffle
方法在数组ref中引入了额外的undef
值。在shuffle
之后,还有一个元素:
my $before_shuffle = bless(
[
"As", "Ks", "Qs", "Js", "10s", "9s", "8s", "7s", "6s", "5s",
"4s", "3s", "2s", "Ah", "Kh", "Qh", "Jh", "10h", "9h", "8h",
"7h", "6h", "5h", "4h", "3h", "2h", "Ad", "Kd", "Qd", "Jd",
"10d", "9d", "8d", "7d", "6d", "5d", "4d", "3d", "2d", "Ac",
"Kc", "Qc", "Jc", "10c", "9c", "8c", "7c", "6c", "5c", "4c",
"3c", "2c",
],
"Deck"
);
my $after_shuffle = bless(
[
"2d", "6s", "3s", "Qs", "7s", "7h", "7d", "4c", "3c", "Jd",
"Js", "Qh", "9s", "Kc", "5d", "2h", "5s", "6h", "Ah", "8s",
"7c", "Qd", "Qc", "3d", "8c", "Jh", "10c", "6c", "Jc", "9h",
"9d", "2s", "4d", "4s", "10d", "9c", "Kd", "6d", "5c", "5h",
"Ks", "8d", "Ad", undef, "As", "8h", "3h", "Kh", "2c", "4h",
"10h", "10s", "Ac",
],
"Deck"
);
它发生在您foreach
shuffle
内my $i = @{$self}; # <-- this is the number of elements in the array
while ($i > 0) {
my $j = int(rand($i));
@{$self}[$i, $j] = @{$self}[$j, $i]; # <-- switch [52, rand] with [rand, 52]
$i--;
}
的第一次迭代中。
$i
52
始终由0
开始。但是您有51
到52
的索引。因此,您随机播放的行将索引$j
分配给索引52
,反之亦然。但是之前未设置索引undef
,因此它是$i
。解决方案是将0
减少一个以匹配51
到my $i = @{$self} - 1;
:
{{1}}