我正在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的新手。
答案 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");
还有很多其他事情要做,这比其需要的要复杂得多。
我建议你做什么:
答案 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';
}