我使用switch语句来检查终端上提供的参数。 如果最终用户提供
,则提供的脚本正常工作 $perl test.pl -help
但是当用户给出下面的选项时,子程序不会被递归调用。
$perl test.pl -link abc -web test.com
Plz建议!
use Switch;
#perl test.pl -help
#perl test.pl -link abc -web test.com
sub CheckArgument {
my ($argv) = shift @_;
local $\ = "\n";
print "\$argv : $argv\n";
switch($argv) {
case /-help/ {
print "Usage : $0 -link <link name> -web <website name>";
print "Usage : $0 -list_web_name";
exit;
}
case /-list_web_name/ {
print "Currently Support following site";
foreach (qw/abc/) {
print "$_";
}
exit;
}
case /-link/ {
CheckArgument($ARGV[3]);
}
case /-web/ {
print "argument provided : @ARGV\n";
}
default {
CheckArgument("-help");
}
}
}
答案 0 :(得分:4)
Switch是一个不适合实际使用的实验模块。 5.10以given
/ when
。
顺便说一下,您可能希望看一下Getopt::Long来更好地处理部分工作。
答案 1 :(得分:2)
首先,不推荐使用Switch
源过滤器。请不要使用它。
这是一个没有递归的代码重写,可能更容易理解:
use 5.010;
sub CheckArgument {
my $_ = shift;
ARG: {
if (/-help/) {
say "Usage: $0 -link <link-name> -web <website-name>";
say "Usage: $0 -list_web_name";
} elsif (/-list_web_name/) {
say "Currently supporting following sites:";
say for qw/a b c/;
} elsif (/-link/) {
$_ = $ARGV[3];
redo ARG;
} elsif (/-web/) {
say "arguments provided : @ARGV\n";
} else {
$_ = "-help";
redo ARG;
}
}
exit;
}
如果我们将@ARGV
设置为qw/ -link x y -web/
,并以@ARGV
作为参数调用该子,我们将获得以下输出:
arguments provided : -link x y -web
首先,我们来看-link
。这导致我们将@ARGV
中的第4个元素放到我们正在查看的变量中。这将在下一次迭代中保留-web
,这将输出所有命令行参数。这种解析策略绝不健全。
当你有未经处理的参数时,比递归更好的是循环。如果您认识到交换机,请从arglist中删除交换机及其值。如果您不理解参数,请打印用法:
use 5.010;
# I use 5.010 for the C<say> function, but if we're already using it,
# we could just as well use given/when. Wouldn't make it much prettier.
sub ProcessArguments {
ARG: while (@_) {
my $_ = shift;
if (/\A-?-list_web_name\z/) {
say "Currently supporting following sites:";
say for qw/a b c/;
} elsif (/\A-?-link\z/) {
my $link_name = shift;
shift() =~ /\A-?-web\z/ or do { Usage(); exit };
my $website_name = shift;
do_something_with($link_name, $website_name);
} elsif (/\A-?-web\z/) {
my $website_name = shift;
shift() =~ /\A-?-link\z/ or do {Usage(); exit };
my $link_name = shift;
do_something_with($link_name, $website_name);
} else {
Usage();
exit;
}
}
}
sub Usage {
say "Usage: $0 -link <link-name> -web <website-name>";
say "Usage: $0 -list_web_name";
}
哦,这个糟糕的样板,无休止的重复。如果有人已经写了一些已经为我们提供选择的东西,那不是很好吗?比如CPAN模块?
use Getopt::Long;
use 5.010;
sub ProcessArguments {
my $list_web_name;
my $help;
my ($link_name, $website_name);
GetOptions
'list-web-name' => \$list_web_name,
'help' => \$help,
'link=s' => \$link_name,
'web=s' => \$website_name;
if ($help) {
Usage();
} elsif ($list_web_name) {
say "Currently supporting following sites:";
say for qw/a b c/;
} elsif (defined $link_name and defined $website_name) {
do_something_with($link_name, $website_name);
} else {
Usage();
}
}
这就是它的完成方式。