繁体   English   中英

在Perl中对其进行修改后获取警告打印数组对象

[英]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 但是您有051索引。 因此,您进行混洗的行会将索引52分配给索引$j ,反之亦然。 但是索引52之前未设置,因此它是undef 解决方案是将$i 1以匹配051

my $i = @{$self} - 1;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM