子例程中的默认参数值

Dav*_*vid 13 perl function subroutine

我不知道如何为子程序设置默认参数.这是我考虑的:

sub hello {
  print @_ || "Hello world";
}
Run Code Online (Sandbox Code Playgroud)

如果您需要的只是一个参数,这样就可以了.您将如何为多个参数设置默认值?

我打算这样做:

sub hello {
  my $say = $_[0] || "Hello";
  my $to  = $_[1] || "World!";
  print "$say $to";
}
Run Code Online (Sandbox Code Playgroud)

但那是很多工作......必须有一个更简单的方法; 可能是最好的做法?

yst*_*sth 14

我用命名参数这样做:

sub hello {
    my (%arg) = (
        'foo' => 'default_foo',
        'bar' => 'default_bar',
        @_
    );

}
Run Code Online (Sandbox Code Playgroud)

我相信Params :: Validate支持默认值,但这比我喜欢的更麻烦.


jse*_*gal 12

我经常这样做:

sub hello {
    my ($say,$to) = @_;
    $say ||= "Hello";
    $to ||= "World!";
    print "$say $to\n";
}
Run Code Online (Sandbox Code Playgroud)

请注意,从perl 5.10开始,您可以使用" //="运算符来测试变量是否已定义,而不仅仅是非零.(想象一下hello("0","friend"),使用上面的调用会产生"Hello friend",这可能不是你想要的.使用//=运算符会产生"0 friend").

  • @Davidmoreen:测试数组的定义是没用的 (4认同)
  • @Davidmoreen,正确的说法是'print $ _ [0] //"Hello world";`.正如ysth所说,你不能在数组上使用`defined`(这就是```的意思),因为标量上下文中的数组返回其长度,该长度始终是定义的. (3认同)

dra*_*tun 7

另外看看Method::Signatures.这用于Devel::Declare提供一些额外的(需要!)糖与关键字methodfunc.

以下是使用新的示例func:

use Method::Signatures;

func hello ($say='Hello', $to='World!') {
    say "$say $to";
}

hello( 'Hello', 'you!' );    # => "Hello you!"
hello( 'Yo' );               # => "Yo World!"
hello();                     # => "Hello World!"
Run Code Online (Sandbox Code Playgroud)

/ I3az /


Nik*_*ain 5

如果您查看Damian ConwayPerl Best Practices : Default argument Values文档,那么您会发现一些重要的要点,例如:

  • @_ 解压后立即解析所有默认参数值。
  • 它建议,如果您要设置许多默认值,那么最干净的方法是将默认值分解到表中,即散列 ,然后使用该表预初始化参数散列。

例子:

#!/usr/bin/perl
  use strict;
  use warning;
  my %myhash = (say => "Hello", to => "Stack Overflow");
  sub hello {
   my ($say, $to) = @_;
   $say =  $say ? $say : $myhash{say};
   $to =  $to ? $to : $myhash{to};
   print "$say $to\n";
  }
  hello('Perl');      # output :Perl Stack Overflow
  hello('','SO');     # output :Hello SO
  hello('Perl','SO'); # output :Perl SO
  hello();            # output :Hello Stack Overflow
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息和完整示例,请参阅Perl 最佳实践


eld*_*his 2

CPAN 上有Attribute::Default模块。可能比这更干净,并且避免了一些复杂性(例如,如果您想传递false给子例程怎么办?)。

我也见过人们使用my $var = exists @_[0] ? shift : "Default_Value";,但 Perl 的文档指出调用exists数组已被弃用,所以我不会真正推荐它。

Attribute::Default文档页面的片段:

  sub vitals : Default({age => 14, sex => 'male'}) {
     my %vitals = @_;
     print "I'm $vitals{'sex'}, $vitals{'age'} years old, and am from $vitals{'location'}\n";
  }

   # Prints "I'm male, 14 years old, and am from Schenectady"
   vitals(location => 'Schenectady');
Run Code Online (Sandbox Code Playgroud)