12

2 つの変数を perl 関数に渡すことを計画していますが、そのうちの 1 つはオプションである可能性があります。2番目のものが定義されているかどうかを確認しようとしていますが、正しく機能しません。関数を myFunction(18) として呼び出すと、変数 $optional が定義されていると見なされ、else ステートメントに移動します。しかし、$optional 変数がアクセスされているときの else ステートメントでは、「初期化されていない」エラーがスローされます。これは、私が予想していたものとは正反対です。どんな助けでも大歓迎です。

sub myFunction {
    my ($length, $optional) = (@_);

    if (undef($optional) {
        more code..
    }
    else {
        more code...
    }
}

myFunction(18);
4

2 に答える 2

23

正しい関数はdefined. undef未定義$optional。あなたがしたいことは次のようなものです:

sub myFunction {
    my($length, $optional) = @_;

    if (!defined $optional) {
        # Do whatever needs to be done if $optional isn't defined.
    }
    else {
        # Do whatever can be done if $optional *is* defined.
    }
}

それに対処する別の方法 (特に Perl 5.10 以降) は、次のように「定義済み or」演算子を使用すること//です。

sub MyFunc {
    my $length = shift;
    my $optional = shift // 'Default Value';
    # Do your stuff here.
}

shift @_の戻り値が定義されているかどうかを検出します。すでに shift を 1 回呼び出しているため、2 番目のパラメーターをテストしています。定義されている場合は、値を に割り当てます$optional。定義されていない場合は、に割り当て'Default Value'ます$optional。もちろん、独自の適切なデフォルトを考え出す必要があります。

Perl 5.10 より前の暗黒時代に行き詰まっている場合は、次の方法で同じことを達成できます。

my $optional = shift;
$optional = defined $optional ? $optional : 'Default value';

...また...

my $length = shift;
my $optional = defined( $_[0] ) ? shift : 'Default value';

いずれにせよ、完全に独立した制御フロー パスよりも、適切なデフォルトを使用することを好むことがよくあります。多くの場合、コードを単純化するための良い方法です。

于 2013-02-09T21:47:29.277 に答える
0
my $optional = defined( $_[0] ) ? shift : 'Default value';

これは、定義されている場合にのみパラメーターをシフトオフするため、危険なコードです。3 番目のパラメーターがあると、呼び出し時に混乱する可能性があります。

MyFunc( 10, undef, 20 )
于 2016-11-16T15:58:20.173 に答える