如何根据perl中的数字输入添加要设置的变量?

时间:2016-01-30 10:38:17

标签: perl

我正在Perl制作一个得分记录脚本,并希望让它询问有多少玩家,并为每个玩家询问一个名字,然后得分。我完成了这个脚本,但只有3个玩家。可以在github上找到当前脚本:skore

(来自链接:)

#!/usr/bin/env perl

use strict;
my $version = "1.0";
my $arg = shift(@ARGV);
my $subname = $arg;
if (!defined($arg)){
    cmd_go();
}
$subname =~ s/-/_/g;
my $sub = main->can("cmd_$subname") || main->can("dev_$subname") || main->can("hid_$subname");
if (!defined($sub))
{
    print STDERR "Invalid command given.\nUse \e[1;32m./skore help\e[0m for a list of commands.\n";
    exit 1;
}
else
{
    $sub->(@ARGV);
    exit 0;
}
# Main command
sub cmd_go()
{
    print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
    print "••••••••••••••••••••\n";
    print "• Welcome to \e[1;32mskore\e[0m •\n";
    print "••••••••••••••••••••\n\n";
    my @game = prompt("What game are we scoring?\n");
    print "••• Game name locked: @game\n\n";
    my @p1name = prompt("Player 1 name?\n");
    my @p2name = prompt("Player 2 name?\n");
    my @p3name = prompt("Player 3 name?\n");
    print "\n";
    print "••• Player names locked: @p1name @p2name @p3name\n\n";
    my @p1score = prompt_num("score for @p1name?\n");
    my @p2score = prompt_num("score for @p2name?\n");
    my @p3score = prompt_num("score for @p3name?\n");
    print "\n";
    print "••• Game: @game\n";
    print "••• @p1name\n";
    print "••••• \e[1;32m@p1score\e[0m\n";
    print "••• @p2name\n";
    print "••••• \e[1;32m@p2score\e[0m\n";
    print "••• @p3name\n";
    print "••••• \e[1;32m@p3score\e[0m\n";
    exit 1;
}
sub cmd_help()
{
    print "To get right into using skore, simply type ./skore\n";
    print "For details about skore, such as version, use ./skore pkg\n";
}
sub cmd_pkg()
{
    print "skore version: $version\n";
    print "Detected OS: ";
    exec "uname -r";
}

sub prompt {
    my ($query) = @_; # take a prompt string as argument
    local $| = 1; # activate autoflush to immediately show the prompt 
    print $query;
    chomp(my $answer = <STDIN>); return $answer;
}
sub prompt_num {
    NSTART:
    my ($querynum) = @_;
    print $querynum;
    chomp(my $pnum = <STDIN>);
    if ($pnum eq $pnum+0) { return $pnum; }
    else { print "Error: That is not a number. Try again.\n"; goto NSTART; }
}
sub prompt_yn {
    my ($queryyn) = @_;
    my $answer = prompt("$queryyn (y/N): ");
    return lc($answer) eq 'y';
}

我还想指出我是perl的新手。

2 个答案:

答案 0 :(得分:6)

好的,哇。停一会儿,退后一步,把代码放下。想想你在这里想要完成的事情。

您在代码中执行的一系列操作确实会从后退中获益,并在继续操作之前了解正在发生的事情。

首先关闭:

my $arg = shift(@ARGV);
my $subname = $arg;
if (!defined($arg)){
    cmd_go();
}

这是打算做什么的?您在这里仅使用$arg次3次,其中一次是将其复制到$subname

这可以通过以下方式简化:

my $subname = shift; 
cmd_go() unless defined $subname; 

现在这个:

my $sub = main->can("cmd_$subname") || main->can("dev_$subname") || main->can("hid_$subname");

那是从哪里来的?因为我非常确定 - 作为perl的初学者 - 你自己也没有写过,尤其是因为你没有任何以dev_或{{1}为前缀的子程序}。对于一个基本上只做一件事的程序来说,这种重定向是严重的过度杀伤。

(通常,您使用hid之类的标志而不是在默认状态下留空的命令。

你也大量过度使用数组 - 这表明你并不确定getopt@game之间的区别。

E.g。这样:

$game

my @game = prompt("What game are we scoring?\n"); 会这样做:

prompt

它会返回一个标量(单行),并且你将它放入一个数组中 - 据我所知 - 没有特别的原因。

同样如此:

chomp(my $answer = <STDIN>); return $answer;

首先 - 你正在使用一堆单个元素数组。但是你要为它们编号。实际上,数组的整个点就是数字值。

那么如何:

my @p1score = prompt_num("score for @p1name?\n");
my @p2score = prompt_num("score for @p2name?\n");
my @p3score = prompt_num("score for @p3name?\n");

还有很多其他事情要做,这比其需要的要复杂得多。

我建议你做什么:

  • 重新阅读perl基础知识。特别是perldata
  • 查看getopt这是一个很好的(和标准的)方式来获取程序&#39;标记&#39;风格输入。 (例如,显示版本,如果那是你真正想要的。
  • 它看起来很像你在货物上抄袭了这里的代码。我建议你从头开始重新编写,当你遇到问题时 - 在Stack Overflow上询问它,如果你不能从perl文档中弄清楚它。

答案 1 :(得分:-4)

试试这个。希望这是你想要的。

#!/usr/bin/env perl

use strict;
my $version = "1.0";
my $arg = shift(@ARGV);
my $subname = $arg;
if (!defined($arg)){
    cmd_go();
}
$subname =~ s/-/_/g;
my $sub = main->can("cmd_$subname") || main->can("dev_$subname") || main->can("hid_$subname");
if (!defined($sub))
{
    print STDERR "Invalid command given.\nUse \e[1;32m./skore help\e[0m for a list of commands.\n";
    exit 1;
}
else
{
    $sub->(@ARGV);
    exit 0;
}
# Main command
sub cmd_go()
{
    print "\e[2J\e[0G\e[0d"; # J = Erase in Display, 2 = Entire Screen, (G, d) = Move cursor to (..,..)
    print "••••••••••••••••••••\n";
    print "• Welcome to \e[1;32mskore\e[0m •\n";
    print "••••••••••••••••••••\n\n";
    my @game = prompt("What game are we scoring?\n");
    print "••• Game name locked: @game\n\n";
    my $players= prompt("Enter total number of players:\n");
    my @players_list;
    for(my $i=0;$i<$players;$i++){
            push(@players_list , prompt("Enter Player ".($i+1)." name\n"));
    }
    print "\n";
            print "••• Player names locked:  ";
    for(my $i=0;$i<$players;$i++){
            print $players_list[$i]."\t";
    }
    print "\n\n";
    my @players_score;
    for(my $i=0;$i<$players;$i++){
            push(@players_score, prompt("score for $players_list[$i]?\n"));
    }
    print "\n";
    print "••• Game: @game\n";
    for(my $i=0;$i<$players;$i++){
            print "$players_list[$i]\n";
            print "••••• \e[1;32m$players_score[$i]\e[0m\n";
    }
    exit 1;
}
sub cmd_help()
{
    print "To get right into using skore, simply type ./skore\n";
    print "For details about skore, such as version, use ./skore pkg\n";
}
sub cmd_pkg()
{
    print "skore version: $version\n";
    print "Detected OS: ";
    exec "uname -r";
}
sub prompt {
    my ($query) = @_; # take a prompt string as argument
    local $| = 1; # activate autoflush to immediately show the prompt 
    print $query;
    chomp(my $answer = <STDIN>); return $answer;
}
sub prompt_num {
    NSTART:
    my ($querynum) = @_;
    print $querynum;
    chomp(my $pnum = <STDIN>);
    if ($pnum eq $pnum+0) { return $pnum; }
    else { print "Error: That is not a number. Try again.\n"; goto NSTART; }
}
sub prompt_yn {
    my ($queryyn) = @_;
    my $answer = prompt("$queryyn (y/N): ");
    return lc($answer) eq 'y';
}