提问人:Igor 提问时间:7/7/2022 最后编辑:Igor 更新时间:7/7/2022 访问量:116
如何重写给定/何时的用法,以消除对其使用的“实验性”警告
How to rewrite uses of given/when so to eliminate "experimental" warnings for their use
问:
都
我有以下几点:
This is perl 5, version 26, subversion 3 (v5.26.3) built for x86_64-linux-thread-multi
(with 57 registered patches, see perl -V for more detail)
Copyright 1987-2018, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
我使用的脚本有 和 .given
when
尝试谷歌我发现了这一点,它说它将以不兼容的方式进行更改。
我在 RHEL8 上并继续前进。
我想修复脚本,以便其他人也能利用脚本,并且不再看到这些警告。
如何重写它以摆脱警告?
TIA!
编辑:
很抱歉不够明确 - 通过修复脚本,我的意思是消除有问题的调用/重写它。
编辑2:
given($pl) {
when(0) { print "A"; }
when(1) { print "B"; }
when(2) { print "C"; }
when(3) { print "D"; }
when(4) { print "E"; }
default { print "Illegal "; }
}
其中只是一个整数(C 中的无符号短整型)。$pl
该脚本从文件中读取一些数据。 该文件包含一些十六进制值。这些值被解析 - 提取一些位,然后将这些位的字符串表示打印在屏幕上。
编辑3:
我尝试使用以下代码:
my %table_pl = (
0 => sub { print "A"; },
1 => sub { print "B"; },
2 => sub { print "C"; },
3 => sub { print "D"; },
4 => sub { print "E"; },
);
for $pl( 0..5 )
{
if( exists $table_pl{$pl} )
{
$table_pl{$pl}->();
}
else
{
print "Illegal ";
}
}
但我收到一个错误:
Number found where operator expected near 1
(Missing semicolon on the previous line?)
答:
2赞
stevieb
7/7/2022
#1
我喜欢使用调度表来做这样的事情。从本质上讲,它是一个哈希值,其中键是有效选项,键的值是一个子例程,在提供有效选项时执行您想要执行的操作。这样做可以消除一长串 if/else 语句。
您可以将子例程内联到表本身中,也可以引用在其他地方定义的子例程。此处的示例显示了以下两种情况:
use warnings;
use strict;
my %table = (
0 => sub { print "A\n"; },
1 => sub { print "B\n"; },
2 => sub { print "C\n"; },
3 => sub { print "D\n"; },
4 => \&code_reference_example,
);
for my $pl (0..5) {
if (exists $table{$pl}) {
# Put the option into the table and execute
# the assigned subroutine
$table{$pl}->();
} else {
print "'$pl' is not a valid option\n";
}
}
sub code_reference_example {
print "E\n";
}
输出:
A
B
C
D
E
'5' is not a valid option
评论
0赞
Igor
7/7/2022
出现错误。你能检查一下我的编辑吗?
0赞
stevieb
7/7/2022
@Igor,错误似乎不是来自编辑中的代码。它必须在该代码之前发生。我看不出你发布的内容有什么问题(除了你的循环中缺少,这表明你没有使用 )。my
for()
strict
0赞
Igor
7/7/2022
是的,对不起。一切都很好。是旧代码的遗留物,我没有注释掉。谢谢。
1赞
ikegami
7/7/2022
#2
given ( $pl ) {
when ( 0 ) { print "A"; }
when ( 1 ) { print "B"; }
when ( 2 ) { print "C"; }
when ( 3 ) { print "D"; }
when ( 4 ) { print "E"; }
default { print "Illegal "; }
}
是
given ( $pl ) {
when ( $_ ~~ 0 ) { print "A"; }
when ( $_ ~~ 1 ) { print "B"; }
when ( $_ ~~ 2 ) { print "C"; }
when ( $_ ~~ 3 ) { print "D"; }
when ( $_ ~~ 4 ) { print "E"; }
default { print "Illegal "; }
}
它可以写成
for ( $pl ) {
if ( $_ ~~ 0 ) { print "A"; }
elsif ( $_ ~~ 1 ) { print "B"; }
elsif ( $_ ~~ 2 ) { print "C"; }
elsif ( $_ ~~ 3 ) { print "D"; }
elsif ( $_ ~~ 4 ) { print "E"; }
else { print "Illegal "; }
}
但问题的关键在于避免损坏/实验性的智能匹配功能。这将是“等价物”:
for ( $pl ) {
if ( !looks_like_number( $_ ) ) {
print "Illegal ";
next;
}
if ( $_ == 0 ) { print "A"; }
elsif ( $_ == 1 ) { print "B"; }
elsif ( $_ == 2 ) { print "C"; }
elsif ( $_ == 3 ) { print "D"; }
elsif ( $_ == 4 ) { print "E"; }
else { print "Illegal "; }
}
它并不完全等同。不同之处在于,最后一个以相同的方式处理数字和字符串。智能匹配以不同的方式对待它们这一事实是它不可接受的设计的全部原因,因此这是可取的。2
2
最后,调度表在这里会更好用。通常使用哈希,但数组可用于给定的示例。
use Scalar::Util qw( looks_like_number );
sub is_nonneg_int {
my $x = shift;
return looks_like_number( $x ) && int( $x ) == $x && $x >= 0;
}
my @dispatch = (
sub { print "A"; },
sub { print "B"; },
sub { print "C"; },
sub { print "D"; },
sub { print "E"; },
);
my $handler = is_nonneg_int( $pl ) ? $dispatch[ $pl ] : undef;
if ( $handler ) {
$handler->();
} else {
print "Illegal ";
}
调度表的优点是可以进行单次查找,而不是多次比较。
评论