繁体   English   中英

perl:在使用“strict refs”时,不能将字符串用作ARRAY引用

[英]perl: Can't use string as an ARRAY ref while “strict refs” in use

我有这个问题,我试图将数组传递给sub,它读取其他一些值。 在这个测试脚本中,我传递的是数组@players的引用,但是它的读取字符串是$ buffer。

use Data::Dumper;

my @players = [];
my @playerscores = [];
my %FORM;

my $buffer = "numplayers=2&changeplayers=3&CHANGEIT=CHANGEIT&player1=a&player2=b&restart=1&newcoords=";

sub testsub {
    my @testee = @$_[0];
    print "in testsub: $testee[0]\n";
}

my @holder = split(/&/,$buffer,);
foreach my $iter (@holder)
{
    my ($name,$value) = split(/=/,$iter);
    $FORM{$name} = $value;
}
$_ = $buffer;
foreach my $key (keys(%FORM))
{
    if($key=~ /player[1-9]/)
    {
        if(!($FORM{$key} eq ""))
        {
            my $holder = $key;
            $holder =~ s/player//;
            $players[$holder] = $FORM{$key};
            $playerscores[$holder] = 0;
            $_ = $buffer;
        }
    }
}

print "\n Data Dumper on player:\n";
print Dumper(@players);
print "\n\n";

print "Check sub:\n";
testsub(\@players,\@playerscores);

输出:

 Data Dumper on player:
$VAR1 = [];
$VAR2 = 'a';
$VAR3 = 'b';


Check sub:
Can't use string ("numplayers=2

&changeplayers=3&CHA"...) as an ARRAY ref while "strict refs" in use at test-str-pool2.pl line 15.

然而,我在期待“a”或“b”作为print "in testsub: $testee[0]\\n";的结果print "in testsub: $testee[0]\\n"; 为什么会这样?

你正在错误地声明你的数组,这就是为什么Dumper输出有[] (一个空数组引用)作为@players的第一个元素。 采用:

my @players = ();
my @playerscores = ();

第二个错误来自:

my @testee = @$_[0];

这会尝试取消引用$_并从结果数组中取出第一个元素。 你的意思是:

my @testee = @{$_[0]};

@_获取第一个元素并取消引用它。

有几件事你做错了。

你有player1player2 您正在使用数组来保存它们,并删除player字符串以获取播放器编号。

没有player0这就是你在数组的第一个值中得到undef原因。

您传入两个数组引用,但只查看一个,并以错误的方式查看它:

我更喜欢这样做:

sub testsub {
    my $testee_ref = shift;
    @testee = @{ $testee_ref };

我喜欢使用shift,因为你正在做的事情更明显。 我更愿意使用两步法(获取引用,然后取消引用该引用)。 但是,你也可以使用:

sub testsub {
    my @testee = @{shift()};

要么

sub testsub {
    my @testee = @{$_[0]};   #Take the reference in $_[0] and dereference it.

无论哪种方式,您现在都会收到错误消息:

Use of uninitialized value $testee[0] in concatenation (.) or string at ./test.pl line 40.

因为你的数组中的第一个元素是未定义的!

看起来您希望以易于访问的格式存储有关播放器及其分数的信息。 我会使用一个参考来将玩家的得分 ,他们的名字以及他们游戏的所有方面放在一起。 您已经了解了引用,因为您正在使用它们:

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw(say);
use Data::Dumper;

my $game = {};   # A reference to a game
$game->{PLAYERS} = {}; # A reference to the players
my $buffer = "numplayers=2&changeplayers=3&CHANGEIT=CHANGEIT&player1=a&player2=b&restart=1&newcoords=";

for my $values ( split /&/, $buffer ) {
    my ($key, $value ) = split /=/, $values;
    if ( $key !~ /^player/ ) {
        $game->{$key} = $value;
    }
    else {
        $game->{PLAYERS}->{$key}->{NAME} = $value;
        $game->{PLAYERS}->{$key}->{SCORE} = 0;
    }
}

say Dumper $game;

# Dumper a player
#

for my $player ( sort keys %{ $game->{PLAYERS} } ) {
    testsub( $game->{PLAYERS}->{$player} );
}

sub testsub {
    my $player_ref = shift;
    say "Player Name = " . $player_ref->{NAME};
    say "Player Score = " . $player_ref->{SCORE};
}

运行这将给你:

$VAR1 = {
        'newcoords' => '',
        'restart' => '1',
        'changeplayers' => '3',
        'numplayers' => '2',
        'PLAYERS' => {
                        'player2' => {
                                        'NAME' => 'b',
                                        'SCORE' => 0
                                    },
                        'player1' => {
                                        'NAME' => 'a',
                                        'SCORE' => 0
                                    }
                    },
        'CHANGEIT' => 'CHANGEIT'
        };

Player Name = a
Player Score = 0
Player Name = b
Player Score = 0

请注意,我有一个名为$game变量,它存储有关游戏的所有信息,包括所有玩家信息。 现在,如果给我一个玩家的参考,我可以打印出该玩家的名字和分数。

更好的是使用面向对象的Perl OOPerl所做的就是使用子程序和对管理这些复杂对象类型的引用的祝福

暂无
暂无

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

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