Go to the first, previous, next, last section, table of contents.

study

`study(SCALAR)'
`study SCALAR'
`study'
SCALAR(指定しなければ $_ )について、 それが次に変更される前に多くのパターンマッチをあらかじめ行う。 検索を行うパターンの性質や数、検索される文字列中の文字の頻度分布により 時間が節約されるかもしれないし、されないかもしれない。 多分これを使用するのとしないのと、 どちらが早く実行できるかを比較してみたいであろう。 数多くの短い定数文字列(より複雑なパターン中の定数部を含む)について 検索を行うループにおいて最も効果があるだろう。 同時に 1 つしか study できない。 別のスカラーを study すると、 最初に study した方は `unstudied' になってしまう。 (study の動作は次のようになる: 検索対象の文字列の全文字の linked list を作り、これにより、例えば、 全ての `k' という文字がどこにあるかがわかる。 C プログラムおよび英文から得た統計的な頻度テーブルに基づいて、 各検索文字列から最も稀な文字を選ぶ。 この"最も稀な"文字を含む位置のみを調べるのである。) 例えば、次のループは、あるパターンを含む行の前に、 インデックスを含むエントリを出力するものである。
while (<>) {
     study;
     print ".IX foo\n" if /\bfoo\b/;
     print ".IX bar\n" if /\bbar\b/;
     print ".IX blurfl\n" if /\bblurfl\b/;
     ...
     print;
}
/\bfoo\b/ を検索する時は、 $_ 中の `f' の位置のみを調べる。 なぜなら、`f'`o' よりも稀だからである。 一般的に、特殊な場合を除いてこれは効果がある。 唯一の問題は、これにより最初に linked list を作るのにかかった以上に 時間を節約できるかどうかである。 注意:
実行時まで決定できない文字列を検索する場合は、 ループを全部文字列としてそれを eval することで 何回も全パターンをコンパイルし直すのを防ぐことができる。 これと合わせて、$/ を全ファイルが 1 レコードになるように undef すると、 大変速く、専用のプログラム fgrep よりも速いことが多い。 以下の例では ファイル群(@files) から単語群(@words) を検索し、 マッチするファイルの名前を出力する。
$search = 'while (<>) { study;';
foreach $word (@words) {
    $search .= "++\$seen{\$ARGV} if /\b$word\b/;\n";
}
$search .= "}";
@ARGV = @files;
undef $/;
eval $search;       # これは大変(this screams)
$/ = "\n";          # 通常の delimiter に戻す
foreach $file (sort keys(%seen)) {
    print $file, "\n";
}

Go to the first, previous, next, last section, table of contents.