2011-12-16 10 views
2

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

($dummy, $class) = split; 

プログラムは、統計がいくつかの統計的分類方法を使用して真実か嘘かをチェックしようとしています。それで、それが計算し、 "真実性"と "虚偽"に次の数を与えると、それは嘘発見器が正しいかどうかをチェックします。 splitのドキュメントから

# 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" 
} 
+2

'のように書くことができる(undefを、$クラス)=スプリット ""、$ _'と' $クラス=(スプリット ""、 ($ダミー、$クラス)=スプリット '(' $ dummy'を使う人がいない限り)と同等の行です。 – hobbs

+1

'perldoc -f split' –

+0

ah yes、コード内に$ _があることがわかりました – alvas

答えて

5
($dummy, $class) = split; 

スプリットは値の配列を返します。最初は$dummyに、2番目は$classに入れられ、それ以上の値は無視されます。最初の引数は、その値を無視する予定のため、dummyという名前が付けられています。より良い選択肢は、undefを使用して が返されたエントリを無視することです:(undef, $class) = split;

Perldocはどのように分割機能を示すことができます。引数なしで呼び出されると、splitは$_に対して動作し、空白で分割されます。 $_はperlのデフォルト変数です。文脈で定義されている暗黙の "it"と考えてください。

暗黙の$ _を使用すると、短いコードをより簡潔にすることができますが、大きなブロック内で使用することは難しいです。あなたは読者があなたと仕事したいと思っていることについて混乱させたくありません。

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文字より長いことに注意してください。)

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

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; 
} 

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

$_ = " ab cd"; 
my @a = split    # @a contains ('ab', 'cd'); 
my @b = split /\s+/, $_; # @b contains ('', 'ab', 'cd') 
3

スプリット/ PATTERN /、EXPR

EXPRが省略されている場合は、$ _の文字列を分割します。 PATTERNも省略すると、 は(空白をスキップして)空白を分割します。何か と一致するパターンは、フィールドを区切る区切り文字と解釈されます。 (区切り文字は1つの文字とは限りません。)パターンと表現の両方が省略されているので、だから、我々は空白にデフォルトの変数$_を分割している

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

このコンテキストでは$_が何であるかを調べるには、周辺のコードを調べる必要があります。ループ変数またはmapブロック内のリスト項目などである可能性があります。

+1

混乱の原因となるだけの未使用変数の導入を避けるため、 '(undef、$ class)= split'を使うのが慣習であることを指摘しておく価値があります。 – flesk

+0

ああ私はそのコードの中ではあまり分かりにくい$ _を見つけました。 – alvas

2

あなたがdocumentationを読めば、あなたはそれを見つけることができます:

  • 最初のオペランドのデフォルトは" "です。
  • 第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 
+0

'3'は文字列を最大3、2を2に、' 1'を1つの文字列に分割すると、 '0'は奇妙なビットです。 – Zaid

+0

@ Zaid、 '-1'および' 0'は制限を課しません。 「0」は空の試行フィールドをトリムする。 – ikegami

関連する問題