14

サブルーチンのデフォルト引数を設定する方法がわかりません。ここに私が考えたものがあります:

sub hello {
  print @_ || "Hello world";
}

必要な引数が 1 つだけの場合は、これで問題なく機能します。複数の引数のデフォルト値をどのように設定しますか?

私はこれをするつもりでした:

sub hello {
  my $say = $_[0] || "Hello";
  my $to  = $_[1] || "World!";
  print "$say $to";
}

しかし、それは大変な作業です...もっと簡単な方法があるはずです。おそらくベストプラクティス?

4

9 に答える 9

14

私は次のように名前付き引数でそれを行います:

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

}

Params::Validateはデフォルト値をサポートしていると思いますが、それは私が望んでいるよりも面倒なことです。

于 2010-08-22T22:11:26.983 に答える
13

私は通常、次のようなことをします:

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

perl 5.10 から、" //=" 演算子を使用して変数が定義されているかどうかをテストできることに注意してください。(呼び出しを想像してみてください。hello("0","friend")上記を使用すると yield が得られ"Hello friend"ますが、これは望んだものではない可能性があります。//=演算子を使用すると、 yield になります"0 friend")。

于 2010-08-22T22:01:20.823 に答える
7

もご覧くださいMethod::Signatures。これは、キーワードandDevel::Declareに追加の (必要な!) シュガーを提供するために使用されます。methodfunc

以下は new を使用した例です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!"

/I3az/

于 2010-08-23T08:40:03.350 に答える
4

Perl Best Practices : Default argument Values by Damian Conwayのドキュメントを参照すると、次のような重要な点がいくつか見つかります。

  • @_ がアンパックされるとすぐに、デフォルトの引数値を解決します。
  • 設定するデフォルト値が多数ある場合、最もクリーンな方法は、デフォルトをテーブル、つまりハッシュに分解し、 そのテーブルで引数ハッシュを事前に初期化することです。

例:

#!/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

詳細と完全な例については、Perl Best Practicesを参照してください。

于 2010-08-23T08:35:39.980 に答える
4

サブルーチンに引数を渡すための Perl のメカニズムは単一のリストであるため、引数は位置指定です。これにより、デフォルト値を提供することが難しくなります。一部のビルトイン ( などsubstr) は、使用される可能性に応じて引数を並べ替えることでこれを処理します。使用頻度の低い引数は最後に表示され、便利なデフォルトがあります。

これを行うよりクリーンな方法は、名前付き引数を使用することです。Perl は名前付き引数自体をサポートしていませんが、ハッシュでそれらをエミュレートできます:

use 5.010;  # for //

sub hello {
    my %arg = @_;
    my $say = delete $arg{say} // 'Hello';
    my $to  = delete $arg{to}  // 'World!';
    print "$say $to\n";
}

hello(say => 'Hi', to => 'everyone');  # Hi everyone
hello(say => 'Hi');                    # Hi world!
hello(to  => 'neighbor Bob');          # Hello neighbor Bob
hello();                               # Hello world!

注: defined-or 演算子//は Perl v5.10 で追加されました。||論理的に偽の値''and をデフォルトにしないため、論理 or ( ) を使用するよりも堅牢です0

于 2010-08-22T22:04:47.000 に答える
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');
于 2010-08-22T22:00:53.477 に答える
1

問題に対処する最良の方法は、他の回答で説明されています。
しかし、私を驚かせることの1つは、あなたが次のように述べていることです:

sub hello {
   print @_ || "Hello world";
}

必要な引数が 1 つだけの場合は、これで問題なく機能します。

実際にそのコードを試しましたか? 引数の数を出力するか、何も指定されていない場合はHello World!
この理由は、|| 演算子が優先され、スカラー コンテキストでは左辺が強制さ@_れるため、引数自体ではなく、提供する引数の数に減ります! Perl の演算子の詳細については、perlop を参照して
ください

HTH、
ポール

于 2010-08-23T12:07:19.013 に答える
0

砂糖の詳細については、Method :: Signatures:も参照してください。

func add($this = 23, $that = 42) {
    return $this + $that;
}
于 2010-08-23T15:48:16.053 に答える