我正在编写一个小的 perl 脚本,主要是为了学习该语言。基本上它有一个动作调度表。根据用户输入,任何一个目标动作都会被调用。每个动作都是一个小的、独立的实用函数(比如打印时间),它让我能够探索和学习 perl 的不同方面。
我遇到了调度机制的问题。该脚本在一个连续循环中运行,每次都接受用户的操作请求。将此输入与每个可用操作的正则表达式进行比较。如果存在匹配,则执行该操作并跳出匹配循环以读取用户的下一个请求。我面临的问题是,如果我两次请求相同的操作,则第二次不匹配。如果我在匹配后立即打印调度表,则匹配的操作条目似乎丢失了。如果我不断请求相同的操作,它仅适用于备用调用。如果我避免使用“最后一个标签”,它可以正常工作。
Perl 版本是 5.12.4(在 Fedora 15 上,32 位)。下面是一个简化但完整的示例。我仍然是 perl 的初学者。如果它不符合僧侣的标准,请原谅:) 请帮助解决此代码的问题。非常感谢您的帮助。
#!/bin/env perl
use strict ;
use warnings ;
use Text::ParseWords ;
my @Actions ;
my $Quit ;
sub main
{
# Dispatch table
# Each row has [syntax, help, {RegExp1 => Function1, RegExp2 => Function2,...}]
# There can be multiple RegExps depending on optional arguments in user input
@Actions =
(
['first <value>', 'Print first', {'first (.*)' => \&PrintFirst} ],
['second <value>', 'Print second', {'second (.*)' => \&PrintSecond} ],
['quit', 'Exits the script', {'quit' => \&Quit} ]
) ;
my $CommandLine ;
my @Captures ;
my $RegEx ;
my $Function ;
while(!$Quit)
{
# Get user input, repeat until there is some entry
while(!$CommandLine)
{
print "\$ " ;
my $argline = <STDIN> ;
my @args = shellwords($argline) ;
$CommandLine = join (" ", grep { length() } @args) ;
}
# Find and execute the action matching given input
# For each entry in the @Actions array
ExecAction: foreach my $Action (@Actions)
{
# For each RegExp for that action (only 1 per action in this example)
while (($RegEx, $Function) = each %{@$Action[2]})
{
if (@Captures = $CommandLine =~ m/^$RegEx$/i)
{
print "Match : $RegEx\n" ;
&$Function(@Captures) ;
last ExecAction ; # Works if this line is commented
}
}
}
$CommandLine = undef ;
}
}
sub PrintFirst { print "first $_[0]\n" ; }
sub PrintSecond { print "second $_[0]\n" ; }
sub Quit { $Quit = 1 ; }
main ;