有没有办法用更好的东西替换Perl中的if-elsif-else?

smi*_*ith 9 perl design-patterns perl-module perl-data-structures

我想构建一堆Perl子程序,它们都具有相同的模板if elsif elsif else,可以根据因子变量做出决定.这是子程序模板的一个例子:

sub get_age{

  my $factor=shift;

  if    ($factor == 1 ){ print "do something" }
  elsif ($factor == 2 ){ print "do somthing2" }
  elsif ($factor == 3 ){ print "do somthing3" }
  elsif ($factor == 4 ){ print "do somthing4" }
  else                 { print "error"        }
  }
Run Code Online (Sandbox Code Playgroud)

我想知道在Perl上是否有一些设计模式if else用更优雅的解决方案替换条件,如果我需要更改某些条件或删除其中某些条件,将来是否容易维护?

bri*_*foy 10

有几个人提到了调度表.有两件事,有时让它们分开是件好事.有可能发生的事情列表,以及使它们发生的事情.如果你把两者结合起来,你就会坚持使用你的解决方案.如果将它们分开,以后会有更大的灵活性.

dispatch表将行为指定为数据而不是程序结构.这有两种不同的方法.在你的例子中,你有整数和类似的东西可能使用数组来存储东西.哈希示例是相同的想法,但略微不同地查找行为.

还要注意我的因素print.当您重复这样的代码时,尝试将重复的内容移动到一个级别.

use v5.10;

foreach my $factor ( map { int rand 5 } 0 .. 9 ) {
    say get_age_array( $factor );
    }

my @animals = qw( cat dog bird frog );
foreach my $factor ( map { $animals[ rand @animals ] } 0 .. 9 ) {
    say get_age_hash( $factor );
    }

sub get_age_array {
    my $factor = shift;

    state $dispatch = [
        sub { 'Nothing!' }, # index 0
        sub { "Calling 1" },
        sub { 1 + 1 },
        sub { "Called 3" },
        sub { time },
        ];

    return unless int $factor <= $#$dispatch;

    $dispatch->[$factor]->();   
    }


sub get_age_hash {
    my $factor = shift;

    state $dispatch = {
        'cat'  => sub { "Called cat" },
        'dog'  => sub { "Calling 1"  },
        'bird' => sub { "Calling 2, with extra" },
        };

    return unless exists $dispatch->{$factor};

    $dispatch->{$factor}->();   
    }
Run Code Online (Sandbox Code Playgroud)


Mar*_*ahl 7

更新:请务必阅读以下brian的评论; 基本上,由于他在链接中评论的各种问题,最好使用for而不是given.我已经更新了我的建议以结合他的改进,他在Use for(而不是given()中概述了它:

如果您使用的是perl 5.10或更高版本,given/when那么您正在寻找神奇的对,但您确实应该使用它for/when.这是一个例子:

use strict;
use warnings;
use feature qw(switch say);

print 'Enter your grade: ';
chomp( my $grade = <> );

for ($grade) {
    when ('A') { say 'Well done!'       }
    when ('B') { say 'Try harder!'      }
    when ('C') { say 'You need help!!!' }
    default { say 'You are just making it up!' }
}
Run Code Online (Sandbox Code Playgroud)

  • 而不是`given`,使用`for`来避免使用`given`的各种错误.请参阅[用于()代替给定()](http://www.effectiveperlprogramming.com/blog/1333). (6认同)