2

この perl スクリプトを解読するのに助けが必要です。$dummy は、スクリプト内の他の場所では何も初期化されていません。スクリプトの次の行は何を意味していますか? また、分割関数にパラメーターがないのはなぜですか?

($dummy, $class) = split;

プログラムは、何らかの統計的分類方法を使用して、ステートメントが真実か嘘かをチェックしようとしています。というわけで、「true-sity」と「falsity」に次の数を計算して与えると、嘘発見器が正しいかどうかをチェックします。

# some code, some code...
$_ = "truth"
# more some code, some code ...

$Truthsity = 9999
$Falsity = 2134123

if ($Truthsity > $Falsity) {   
    $newClass = "truth";      
} else {
    $newClass = "lie";     
}

($dummy, $class) = split;

if ($class eq $newClass) {
    print "correct";
} elsif ($class eq "true") {
    print "false neg";
} else {
    print "false pos"
}
4

3 に答える 3

5
($dummy, $class) = split;

Split は、値の配列を返します。$dummy最初の値はに、2 番目の値はに入れられ、$classそれ以降の値は無視されます。作成者がその値を無視することを計画しているため、最初の引数はおそらくダミーと名付けられています。より良いオプションは、返されたエントリを無視するために undef を使用することです:( undef, $class ) = split;

Perldoc は、どのように分割が機能するかを示すことができます。引数なしで呼び出された場合、split は$_空白に対して動作し、空白で分割されます。 $_は perl のデフォルト変数です。コンテキストによって定義される暗黙の「それ」と考えてください。

暗黙の $_ を使用すると、短いコードをより簡潔にすることができますが、大きなブロック内で使用するのは適切ではありません。どの「それ」を扱いたいかについて、読者を混乱させたくありません。

split ;                      # split it
for (@list) { foo($_) }      # look at each element of list, foo it.
@new = map { $_ + 2 } @list ;# look at each element of list, 
                             # add 2 to it, put it in new list
while(<>){ foo($_)}          # grab each line of input, foo it.

perldoc -f split

EXPR が省略された場合、$_ 文字列を分割します。PATTERN も省略されている場合は、空白で分割されます (先頭の空白をスキップした後)。PATTERN に一致するものはすべて、フィールドを区切る区切り文字と見なされます。(区切り文字は 1 文字より長くなる可能性があることに注意してください。)

私は、? :文字列値を設定し、ロジックをブロックやサブルーチンにプッシュするための三項演算子の大ファンです。

my $Truthsity = 9999
my $Falsity   = 2134123

print test_truthsity( $Truthsity, $Falsity, $_ );

sub test_truthsity {
  my ($truthsity, $falsity, $line ) = @_;
  my $newClass = $truthsity > $falsity ? 'truth' : 'lie';
  my (undef, $class) = split /\s+/, $line ;

  my $output = $class eq $newClass ? 'correct' 
             : $class eq 'true'    ? 'false neg'
             :                       'false pos';
  return $output;
}

このバージョンには微妙なバグがあるかもしれません。 splitwith no args は とまったく同じではありませんsplit(/\s+/, $_)。行がスペースで始まる場合、動作が異なります。完全修飾された分割では、空白の先行フィールドが返されます。 split引数なしで先頭のスペースを削除します。

$_ = "  ab cd";
my @a = split             # @a contains ( 'ab', 'cd' );
my @b = split /\s+/, $_;  # @b contains ( '', 'ab', 'cd')
于 2011-12-16T21:11:22.573 に答える
3

のドキュメントからsplit

分割 /PATTERN/,EXPR

EXPR が省略された場合、$_ 文字列を分割します。PATTERN も省略されている場合は、空白で分割されます (先頭の空白をスキップした後)。PATTERN に一致するものはすべて、フィールドを区切る区切り文字と見なされます。(区切り文字は 1 文字より長くなる可能性があることに注意してください。)

したがって、パターンと式の両方が省略されているため、デフォルト変数$_を空白で分割しています。

この変数の目的は、$dummysplit から返されたリストの最初の要素をキャプチャして無視することです。これは、コードが 2 番目の要素にのみ関心があるため$classです。

$_このコンテキストにあるものを見つけるには、周囲のコードを調べる必要があります。ループ変数またはmapブロック内のリスト項目、またはその他のものである可能性があります。

于 2011-12-16T21:10:39.750 に答える
2

ドキュメントを読むと、次のことがわかります。

  • 最初のオペランドのデフォルトは です" "
  • 2 番目のオペランドのデフォルトは です$_
  • 3 番目のオペランドのデフォルトは です0

それで

split

の略です

split " ", $_, 0

そして、それは次のことを意味します:

$_ を取り、その値を空白で分割し、先頭と末尾の空白を無視します。

結果の最初のフィールドは に配置され$dummy、2 番目のフィールドは に配置され$classます。

その名前に基づいて、二度と使用$dummyしないと思われるので、単にプレースホルダーとして機能しています. しかし、あなたはそれを取り除くことができます。

my ($dummy, $class) = split;

次のように書くことができます

my (undef, $class) = split;   # Use undef as a placeholder

また

my $class = ( split )[1];     # Use a list slice to get second item
于 2011-12-17T05:44:30.310 に答える