我正在做一些Perl并且看到我的嵌套“if”语句让我发疯。我设法在另一部分中使用防护块来减少其中一些,但我被困在这里。
您认为我可以保留代码,还是有一种“正确”的方式来重构以下内容? (我也承认对Perl来说比较新)
这实际上是一个子程序,要求用户输入列表的每个参数(外部文件)。 $ [3]是匹配模式,$ [2]是所考虑参数的默认值(如果没有则为NULL),$ _ [1]指定它是否是必需的。 'next'语句引用下一个参数read(while循环)。
在大家的帮助下(谢谢!),这是最新版本。
100 if ( $input ne '' && ( $input !~ $match || $input =~ /'.+'/ ) ) {
101 print "! Format not respected. Match : /$match/ (without \' \')\n";
102 next;
103 }
104 if ( $input eq '' ) {
105 if ( $default eq 'NULL' ) {
106 if ( $manda eq 'y' ) {
107 print "! Mandatory parameter not filled in\n";
108 next;
109 }
110 print "+ Ignoring parameter.\n";
111 $input = '';
112 }
113 else {
114 print "+ Using default value\n";
115 $input = $default;
116 }
117 }
98 if($input eq ''){
99 if($_[2] eq 'NULL'){
100 if($_[1] eq 'y'){
101 print "! Mandatory parameter not filled in\n";
102 next;
103 }
104 else{
105 print "+ Ignoring parameter.\n";
106 $input = '';
107 }
108 }
109 else{
110 print "+ Using default value\n";
111 $input = $_[2];
112 }
113 }
114 elsif($input !~ $_[3] || $input =~ /'.+'/){
115 print "! Format not respected. Match : /$_[3]/ (without \' \')\n";
116 next;
117 }
118 }
答案 0 :(得分:10)
这是一个稍微更易读的混沌答案版本:
# Set sane variable names...
my ($is_required, $default, $pattern) = @_
# Convert the external string convention for simpler evaluation...
$default = undef if $default eq 'NULL'
# Refuse problematic input before going any further...
if ($input ne '' && $input !~ $pattern || $input =~ /'.+'/) {
print "! Format not respected. Match : /$pattern/ (without \' \')\n";
next;
}
# If there was no input string...
if($input eq '') {
# Set the default, if one was provided...
if( $default ) {
print "+ Using default value\n";
$input = $default;
}
# otherwise, complain if a default was required...
else {
if( $is_required eq 'y' ){
print "! Mandatory parameter not filled in\n";
next;
}
print "+ Ignoring parameter (no input or default provided).\n";
}
}
关键点是:
答案 1 :(得分:4)
有时有助于提高可读性的另一种方法是将部分或全部分支放在命名良好的代码引用中。以下是这个想法的开始:
$format_not_respected = sub {
return 0 if ...;
print "! Format not respected....";
return 1;
}
$missing_mandatory_param = sub {
return 0 if ...;
print "! Mandatory parameter not filled in\n";
return 1;
}
next if $format_not_respected->();
next if $missing_mandatory_param->();
etc...
答案 2 :(得分:3)
if($input ne '' && ($input !~ $_[3] || $input =~ /'.+'/)) {
print "! Format not respected. Match : /$_[3]/ (without \' \')\n";
next;
}
if($input eq '') {
if($_[2] eq 'NULL') {
if($_[1] eq 'y'){
print "! Mandatory parameter not filled in\n";
next;
}
print "+ Ignoring parameter.\n";
$input = '';
} else {
print "+ Using default value\n";
$input = $_[2];
}
}
答案 3 :(得分:3)
主要关注的是保持代码可读。
如果您可以使用嵌套的if语句获取可读代码,请继续。但始终保持常识活跃。
答案 4 :(得分:2)
通常的做法是为数组索引定义常量,并为它们指定有意义的名称。如:
use constant MANDATORY => 1,
DEFAULT => 2,
PATTERN => 3;
...
if($_[DEFAULT] eq 'NULL') {
...
}
至于嵌套 - 您应该经常尝试减少缩进(意味着保持嵌套级别低),但绝不会这样做,代价是保持代码可以理解。我对嵌套级别没有任何问题,但这也只是代码的一小部分。如果它确实是一个问题,你可以将条件分解为单独的子程序。
答案 5 :(得分:1)
如果逻辑需要嵌套if语句,那么我猜它们没有任何问题。
但是,您可以通过
提高代码的可读性这不是更具可读性吗?
98 if ($input eq '') {
99 if ($default eq 'NULL'){
100 if ($input eq 'y'){
101 print "! Mandatory parameter not filled in\n";
102 next;
103 }
104 else {
105 print "+ Ignoring parameter.\n";
106 $input = '';
107 }
108 }
109 else {
110 print "+ Using default value\n";
111 $input = $default;
112 }
113 }
114 elsif ($input !~ $foo || $input =~ /'.+'/) {
115 print "! Format not respected. Match : /$foo/ (without \' \')\n";
116 next;
117 }
118 }
答案 6 :(得分:0)
鉴于你可能会做一个意大利面goto
,否则,绝对不会。
可能更好的是switch case。
答案 7 :(得分:0)
如果您不喜欢其他所有内容,可以简化以下内容。
if($input eq ''){
$input = $_[2];
$output = "+ Using default value\n";
if($_[2] eq 'NULL'){
$input = '';
$output = "+ Ignoring parameter.\n";
if($_[1] eq 'y'){
$output = "! Mandatory parameter not filled in\n";
}
}
}
elsif($input !~ $_[3] || $input =~ /'.+'/){
$output = "! Format not respected. Match : /$_[3]/ (without \' \')\n";
}
print $output;
答案 8 :(得分:0)
我认为关注嵌套的主要原因(如果不仅仅是)是算法的复杂性。在其他情况下,您应该担心可读性和可维护性,这可以通过propoer评论和缩进来解决。
我总是找到一个良好的可操作性练习来阅读我的旧代码,不仅仅是关于可读性的反馈,还有技术......
答案 9 :(得分:-2)
我想你可以做逻辑组合来展平它:
if(($input eq '')&&($_[2] eq 'NULL')&&($_[1] eq 'y')){
print "! Mandatory parameter not filled in\n";
next;
}
elsif(($input eq '')&&($_[2] eq 'NULL')){
print "+ Ignoring parameter.\n";
$input = '';
}
elsif($input eq ''){
print "+ Using default value\n";
$input = $_[2];
next;
}
elsif($input !~ $_[3] || $input =~ /'.+'/){
print "! Format not respected. Match : /$_[3]/ (without \' \')\n";
}
print $output;
然后你可以用一个开关来使它好一点。