3

RSSフィードを更新するPerlサブルーチンがあります。$_戻り値をテストしたいのですが、関数は多くの場所で使用されているので、変数が指定されていない場合は、デフォルトの変数をテストしたかったのです。

コードは少し長すぎてすべてを含めることはできませんが、本質的には次のようになります

sub updateFeed {
  #....
  if($error) {
    return 0;
  }
  return 1;
}

なぜですか

$rtn = updateFeed("My message");
if ($rtn < 1) { &Log("updateFeed Failed with error $rtn"); }

エラーをログに記録しない

一方

updateFeed("myMessage");
if ($_ < 1) { &Log("updateFeed Failed with error $_"); }

「」のエラーをログに記録しますupdateFeed Failed with errorか?(メッセージの最後に値がないことに注意してください。)

デフォルトの変数に空の文字列またはundefが含まれているように見える理由を誰かに教えてもらえますか?

4

4 に答える 4

9

Perlはそのようには機能しないからです。$_voidコンテキストで呼び出された関数の結果を自動的に取得しません。$_読み取りと書き込みを行う組み込み演算子がいくつかあり@_ますが、デフォルトでは、独自のサブルーチンは、それを実現するためのコードを記述した場合にのみそれを実行します。

于 2013-01-24T01:26:11.200 に答える
7

$_通常の関数呼び出しは、暗黙的に使用されるコンテキストの1つではありません。

これperldoc perlvarが(v5.14.1の時点で)言わなければならないこと$_です:

$_
デフォルトの入力およびパターン検索スペース。次のペアは同等です。

    while (<>) {...}    # equivalent only in while!
    while (defined($_ = <>)) {...}

    /^Subject:/
    $_ =~ /^Subject:/

    tr/a-z/A-Z/
    $_ =~ tr/a-z/A-Z/

    chomp     
    chomp($_) 

使用しなくてもPerlが$_を想定する場所は次のとおりです。

  • 次の関数は、デフォルトの引数として$_を使用します。

    abs、alarm、chomp、chop、chr、chroot、cos、defined、eval、exp、glob、hex、int、lc、lcfirst、length、log、lstat、mkdir、oct、ord、pos、print、quotemeta、readlink、 readpipe、ref、require、reverse(スカラーコンテキストのみ)、rmdir、sin、split(2番目の引数)、sqrt、stat、study、uc、ucfirst、unlink、unpack。

  • デフォルトがSTDINである、を除くすべてのファイルテスト(-f、 )。perlfuncで見る-d-t-X

  • パターンマッチング操作m//s///およびtr///(別名y///=~演算子なしで使用した場合。

  • foreach他の変数が指定されていない場合のループ内のデフォルトのイテレータ変数。

  • grep()andmap()関数の暗黙のイテレータ変数。

  • の暗黙の変数given()

  • <FH>テストの唯一の基準として、操作の結果が単独でテストされるときに入力レコードを配置するデフォルトの場所while。テスト以外ではwhile、これは起こりません。

$ _はグローバル変数であるため、これにより、場合によっては望ましくない副作用が発生する可能性があります。perl 5.9.1以降、ファイルまたはブロックで$ _を宣言することにより、レキシカルバージョンの$_を使用できるようになりましたmy。さらに、宣言our $_すると、現在のスコープでグローバル$_が復元されます。

ニーモニック:アンダースコアは特定の操作で理解されます。

于 2013-01-24T02:34:31.653 に答える
5

にフラグを割り当てたことがないのに$_、なぜフラグが含まれているのでしょうか。空の文字列(またはundef、警告付きで空の文字列に文字列化される)が含まれているようです。

于 2013-01-24T01:32:50.017 に答える
0

$_デフォルトでは、voidコンテキストのサブルーチンによって設定されません。$_が無効なコンテキストである場合に設定するために潜水艦を書くことが可能です。の値を確認することから始め、が未定義の場合wantarrayに設定します。$_wantarray

sub updateFeed {
  ...
  my $return
  ...

  if($error) {
    $return = 0;
  }else{
    $return = 1;
  }
  # $return = !$error || 0;

  if( defined wantarray ){ # scalar or list context
    return $return;
  }else{ # void context
    $_ = $return;
  }
}

サブルーチンを使用している人にとっては非常に驚きである可能性があるため、これを行うことはお勧めしません。これにより、プログラムのデバッグが困難になる可能性があります。

私がこれを行うのは、組み込みのサブルーチンをエミュレートするときだけです。

于 2013-01-31T03:57:48.493 に答える