[英]Getting a warning printing array object after it's modified in Perl
我正在尝试编写一个简单的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
我究竟做错了什么? 谢谢!
您的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
1以匹配0
到51
:
my $i = @{$self} - 1;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.