perl-5.24.1
study SCALAR
study

Note that since Perl version 5.16 this function has been a no-op, but this might change in a future release.

Perl バージョン 5.16 からこの関数は何もしませんが、これは将来のリリースで 変更されるかもしれないことに注意してください。

May take extra time to study SCALAR ($_ if unspecified) in anticipation of doing many pattern matches on the string before it is next modified. This may or may not save time, depending on the nature and number of patterns you are searching and the distribution of character frequencies in the string to be searched; you probably want to compare run times with and without it to see which is faster. Those loops that scan for many short constant strings (including the constant parts of more complex patterns) will benefit most.

次に変更される前に、この文字列で多くのパターンマッチングを行うと予想して SCALAR (未指定の場合は $_) を学習するために追加の時間を 使います。 これは、検索するパターンの数と性質、および検索される文字列の文字頻度の 分散によって、時間短縮になることもならないことにもなります; おそらくどちらが速いかを調べるためにこれありとなしとで実行時間を 比較した方がよいでしょう。 多くの短い固定文字列(より複雑なパターンの固定部分を含む)をスキャンする ループで最も効果があります。

(The way study used to work is this: a linked list of every character in the string to be searched is made, so we know, for example, where all the 'k' characters are. From each search string, the rarest character is selected, based on some static frequency tables constructed from some C programs and English text. Only those places that contain this "rarest" character are examined.)

(study の動作方法は次のものでした: 検索される文字列の 全ての文字のリンクリストが作られるので、例えば、全ての 'k' 文字が どこにあるかを知ります。 各検索文字列から、いくつかの C プログラムと英文から構築された 静的頻度テーブルを基に最も頻度の少ない文字が選ばれます。 この「もっとも稀な」文字を含む場所のみが調べられます。)

For example, here is a loop that inserts index producing entries before any line containing a certain pattern:

たとえば、特定のパターンを含む行の前にインデックスを 付けるエントリを入れる例を示します。

    while (<>) {
        study;
        print ".IX foo\n"    if /\bfoo\b/;
        print ".IX bar\n"    if /\bbar\b/;
        print ".IX blurfl\n" if /\bblurfl\b/;
        # ...
        print;
    }

In searching for /\bfoo\b/, only locations in $_ that contain f will be looked at, because f is rarer than o. In general, this is a big win except in pathological cases. The only question is whether it saves you more time than it took to build the linked list in the first place.

fo よりも珍しいので、/\bfoo\b/ を探すとき、$_f を含む場所だけが探されます。 一般に、病的な場合を除いて、かなりの結果が得られます。 唯一の問題は、節約できる時間が、最初にリンクリストを作る 時間よりも多いかどうかです、

Note that if you have to look for strings that you don't know till runtime, you can build an entire loop as a string and eval that to avoid recompiling all your patterns all the time. Together with undefining $/ to input entire files as one record, this can be quite fast, often faster than specialized programs like fgrep(1). The following scans a list of files (@files) for a list of words (@words), and prints out the names of those files that contain a match:

実行時まで、探そうとする文字列がわからないときには、 ループ全体を文字列として組み立てて、eval すれば、 いつも、すべてのパターンを再コンパイルするという事態は避けられます。 ファイル全体を一つのレコードとして入力するために、 $/ を未定義にすれば、かなり速くなり、 多くの場合 fgrep(1) のような専用のプログラムより速くなります。 以下の例は、ファイルのリスト (@files) から単語のリスト (@words) を 探して、マッチするものがあったファイル名を出力します。

    my $search = 'local $/; while (<>) { study;';
    foreach my $word (@words) {
        $search .= "++\$seen{\$ARGV} if /\\b$word\\b/;\n";
    }
    $search .= "}";
    @ARGV = @files;
    my %seen;
    eval $search;        # this screams
    foreach my $file (sort keys(%seen)) {
        print $file, "\n";
    }