如何将可选参数传递给函数

时间:2014-12-16 15:12:25

标签: perl function subroutine

我正在尝试为模块创建一个函数,接受以下形式的可选参数:

function(arg1, optional1 => opt1, optional2 => opt2, ..);

然而,我找不到任何可以解释如何做到这一点的好解释。我提出了以下解决方案来接受emailalphahtml个参数,但它非常复杂,我无法相信没有更短的方法来实现这一点:< / p>

sub test
{
    my ($s, @args) = @_;
    my $alpha = 1;
    my $html = 0;
    my $email = 0;
    for(my $i = 0; $i < scalar(@args); $i++)
    {
        if($args[$i] eq "alpha")
        {
            $i++;
            $alpha = $args[$i];
        }
        elsif($args[$i] eq "email")
        {
            $i++;
            $email = $args[$i];
        }
        elsif($args[$i] eq "html")
        {
            $i++;
            $html = $args[$i];
        }
    }
    return ($alpha, $email, $html);
}

my ($a, $b, $c) = test("stuff", ndhgffs => 1, email => 1, alpha => 0);

print $a . $b . $c;

修改

感谢下面的回答和下面的评论,这解决了它:

sub test
{
   my ($s, %opts) = @_;
   my $email = $opts{'email'} // 0;
   my $alpha = $opts{'alpha'} // 1;
   my $html = $opts{'html'} // 0;
   return ($alpha, $email, $html);
}

2 个答案:

答案 0 :(得分:4)

sub function {
   my $arg1 = shift;
   my $arg2 = shift;
   my %opts = @_;
   my $optional1 = delete($opts{$optional1});
   my $optional2 = delete($opts{$optional2});
   croak("Unrecognized parameters ".join(' ', keys(%opts))) if %opts;
   ...
}

sub function {
   my ($arg1, $arg2, %opts) = @_;
   my $optional1 = delete($opts{$optional1});
   my $optional2 = delete($opts{$optional2});
   croak("Unrecognized parameters ".join(' ', keys(%opts))) if %opts;
   ...
}

注意:

  • 如果您不想费心检查无法识别的选项,则不需要delete

  • 您可以在省略参数时使用

    轻松指定默认值
    my $arg = delete($opts{$arg}) // 'default';   # Perl 5.10+
    

答案 1 :(得分:0)

如果子例程参数是从@_的值复制并分配给函数“按出现顺序”的变量,则可以将您的函数写入可以使用{{3设置的默认值或者,如果这些值是真正可选的并且并不总是需要,那么您可以分配占位符值(例如 not_set),然后在函数读入其参数后删除/删除来自@_,例如:

for (keys %opthash){ if ($opthash{$_} =~ /not_set/)  {delete $opthash{$_} }}

如果此功能经常使用,我不确定这是最有效的方法。