【发布时间】:2013-06-07 22:34:56
【问题描述】:
在我们公司,我们使用这个代码(在最后给出)大约 10 年,它运行良好。
前几天我们遇到了一些问题,我们不得不重新编码完整的包,我们决定用 Damian 的 Switch 模块替换这段代码(以提高代码的可读性)。
对我们来说一切都很好。
后来我在Perlmonks 上发现达米安把这个模块放在了
您不应该在生产环境中使用 Damian 模块,因为它们的用途 是探索和原型化未来的核心语言功能。
但它对我们来说很好,因为我们没有达到这个模块的限制(我猜)。
现在我请你们看看这两个实现(嵌套 if else 与 switch),让我知道在较新的实现中使用 Switch 是否很好,或者我们是否会为我们创造一些未来的问题?在下面给出的代码中使用 Switch 是否正常,或者是否有任何隐藏的错误/问题?
我已经在 CPAN 和 Perlmonks 上阅读了此模块的错误和评论,我想我们的代码距离这些错误还很远(我想是的)。
我们正在使用Perl 5.8.5。
PS: 我知道 Switch 的替代方案,我们在 Perl 5.10 中有 given/when,我们可以使用 dispatch table 和指定 here 的其他解决方案,但现在我们只想比较使用 Switch 的新实现。
使用嵌套 if else
if ($command =~ /^enter$/) {
$self->show_main_frames();
}
elsif ($command =~ /^XYZ_MENU/i) {
$self->show_main_menu($manual, $dbot);
}
elsif ($command =~ /^DBOT/i) {
$dbot->process();
}
# XML is used for the reminders-history: Request 2666
elsif ($command =~ /^XML_DBOT/i) {
$dbot->process();
}
elsif ($command =~ /^UGS/i) {
$ugsui->process();
}
elsif ($command eq "kill") {
my $login = $self->{COMMON_HASH}{login} || "";
my $su_login = $self->{CONF}->get("start", "SU_LOGIN");
if ($login eq $su_login) {
# usually only certain user with certain permission will be
# able to do this.
$self->do_error("Daemon was killed by ".$login);
$self->db_connection->disconnect();
$self->{LOG}->write("User $login killed the daemon", 0);
exit; # this 'exit' actually kill the daemon
}
else {
$self->do_error("User $login tried to kill the daemon. ".
"This incident will be reported");
$self->{LOG}->write("User $login tried to kill the daemon", 2);
}
}
elsif ($command eq "logout") {
# check if we should delete the password cookie
my $forget_me = $self->{CGI}->param("forget_me") || 0;
if ($forget_me) {
$self->{DB_PASSWORD_COOKIE}->delete_cookie();
}
$ugsui->do_logout();
# Cliff edit remove id from logged_in
$session->remove_session($session->login());
# delete the session of the user
delete $self->{SESSIONS}{$session->id()};
if ($self->{CACHE_TO_FILE}) {
my $session_data_path =
XYZ_DIR
."/code/cache/session_data"
.$session->id();
unlink($session_data_path);
}
}
# if we just login we should create all the main frames
elsif ($command eq "login") {
# if extra_param holds "command*XXX" the XXX will be placed instead of
# the command. extra_param holds pairs that are astrics-separated
my $extra_param = $cgi->param("extra_param");
$extra_param = "" if (!defined($extra_param));
$extra_param =~ /command\*([^\*]+)/i;
my $other_command = defined($1) ? $1 : "";
if ($other_command =~ /^dbot/i) { # meanwhile - works only on dbot
# commands
$command = $other_command;
# now we will get the other parameters from the extra_param
# (actually including the command that is still in the
# $extra_param)
while ($extra_param =~ /^\*?([^\*]+)\*([^\*]+)(.*)/) {
$extra_param = $3;
my $name = $1;
my $value = $2;
$cgi->param(-name => $name,
-value => $value);
}#end while
}#end if
else{
$self->show_main_frames();
}
}#end elsif
else {
$self->show_main_frames();
}#end outer else
使用开关
switch ($command)
{
case /^enter$/ { $self->show_main_frames() }
case /^XYZ_MENU/i { $self->show_main_menu($manual, $dbot) }
case /^DBOT/i { $dbot->process() }
case /^XML_DBOT/i { $dbot->process() }
case /^UGS/i { $ugsui->process() }
case "kill" {
my $login = $self->{COMMON_HASH}{login} || "";
my $su_login = $self->{CONF}->get("start", "SU_LOGIN");
if ($login eq $su_login) {
# usually only certain user with certain permission will be
# able to do this.
$self->do_error("Daemon was killed by ".$login);
$self->db_connection->disconnect();
$self->{LOG}->write("User $login killed the daemon", 0);
exit; # this 'exit' actually kill the daemon
}
else {
$self->do_error("User $login tried to kill the daemon. ".
"This incident will be reported");
$self->{LOG}->write("User $login tried to kill the daemon", 2);
}
}
case "logout" {
# check if we should delete the password cookie
my $forget_me = $self->{CGI}->param("forget_me") || 0;
if ($forget_me) {
$self->{DB_PASSWORD_COOKIE}->delete_cookie();
}
$ugsui->do_logout();
# Cliff edit remove id from logged_in
$session->remove_session($session->login());
# delete the session of the user
delete $self->{SESSIONS}{$session->id()};
if ($self->{CACHE_TO_FILE}) {
my $session_data_path =
XYZ_DIR
."/code/cache/session_data"
.$session->id();
unlink($session_data_path);
}
}
case "login" {
# if extra_param holds "command*XXX" the XXX will be placed instead of
# the command. extra_param holds pairs that are astrics-separated
my $extra_param = $cgi->param("extra_param");
$extra_param = "" if (!defined($extra_param));
$extra_param =~ /command\*([^\*]+)/i;
my $other_command = defined($1) ? $1 : "";
if ($other_command =~ /^dbot/i)
{ # meanwhile - works only on dbot
# commands
$command = $other_command;
# now we will get the other parameters from the extra_param
# (actually including the command that is still in the
# $extra_param)
while ($extra_param =~ /^\*?([^\*]+)\*([^\*]+)(.*)/) {
$extra_param = $3;
my $name = $1;
my $value = $2;
$cgi->param(-name => $name,
-value => $value);
}#end while
}#end if
else {$self->show_main_frames();}
}
else {$self->show_main_frames();}
} # end switch
【问题讨论】:
-
你为什么要使用这么古老的 Perl 版本。当前版本是 5.16.2,因此您错过了 5.10、5.12、5.14 和 5.16 系列中的改进和错误修复。 Perl 5.8.5 于 2004 年 7 月发布。那是很久以前的事了。
-
我知道,但没办法。我个人使用 5.12,但在公司中我必须使用 5.8.5。顺便说一句,我们将在下一个实现(我们产品的新版本)中使用 5.12。
-
@JonathanLeffler 这是 RHEL 5 提供的版本,它仍然被广泛使用。 Red Hat 实际上会在 2017 年之前支持该版本的 perl(带有付费扩展支持)。
-
取决于您所说的“支持”是什么意思。其中有很多 RH 无法修复的错误。例如它甚至不是该版本的最新版本(5.8.9 是)。
-
RHEL 5 提供 5.8.8。至少,您应该对此进行更新。
标签: perl if-statement switch-statement