10

ファイルグロブに関するPerlのドキュメントによると、<*>演算子またはglob()関数は、スカラーコンテキストで使用される場合、指定されたパターンに一致するファイルのリストを反復処理し、呼び出されるたびに次のファイル名を返す必要があります。これ以上ファイルがない場合はundef。

ただし、反復プロセスはループ内からのみ機能するようです。ループに入っていない場合は、すべての値が読み取られる直前に最初からやり直しているようです。

Perlドキュメントから:

スカラーコンテキストでは、globはそのようなファイル名展開を繰り返し、リストが使い果たされるとundefを返します。

http://perldoc.perl.org/functions/glob.html

ただし、スカラーコンテキストでは、演算子は呼び出されるたびに次の値を返すか、リストがなくなるとundefを返します。

http://perldoc.perl.org/perlop.html#I/O-Operators

コード例:

警告を使用します。
厳密に使用します。

私の$filename;

#スカラーコンテキストでは、<*>は次のファイル名を返す必要があります
#リストがなくなると呼び出されるかundefされるたび

$ filename = <*>;
印刷"$filename \ n";
$ filename = <*>; #文書化されたとおりに機能せず、最初からやり直して
印刷"$filename \ n"; #常に同じファイル名を返します
$ filename = <*>;
印刷"$filename \ n";

印刷"\n";

$ filename=<*>の間に"$filename\n"を出力します。#ループで動作し、次のファイルを返します
                                           #呼び出されるたび

3つのファイル...file1.txt、file2.txt、およびfile3.txtがあるディレクトリでは、上記のコードは次のように出力されます。

file1.txt
file1.txt
file1.txt

file1.txt
file2.txt
file3.txt

注:実際のperlスクリプトは、テストディレクトリの外にある必要があります。そうでない場合は、スクリプトのファイル名も出力に表示されます。

私はここで何か間違ったことをしていますか、それともこれがどのように機能するはずですか?

4

4 に答える 4

9

glob オペレーターの状態の魔法を<>、通常の方法で操作できるオブジェクトに取り込む方法を次に示します。匿名サブ (および/またはクロージャー) です!

sub all_files {
    return sub { scalar <*> };
}

my $iter = all_files();
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

多分:

sub dir_iterator {
    my $dir = shift;
    return sub { scalar glob("$dir/*") };
}
my $iter = dir_iterator("/etc");
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

それからまた、私の傾向はこれを「好奇心」の下に提出することです. glob()/のこの特定の奇妙さを無視して、代わりに/ 、IO::All / 、またはFile::Glob<>を使用してください :)opendirreaddirreaddir

于 2010-04-13T23:57:32.413 に答える
5

次のコードも、イテレータの2つの別個のインスタンスを作成しているようです...

for(1..3)
{{
   $ filename = <*>;
   $ filenameが定義されている場合は、「$ filename\n」を出力します。
   $ filename = <*>;
   $ filenameが定義されている場合は、「$ filename\n」を出力します。
}

私はそこに論理があると思いますが、それは一種の直感に反し、ドキュメントと矛盾しています。ドキュメントには、反復が機能するためにループに入る必要があることについては何も言及されていません。

于 2010-04-13T22:30:22.210 に答える
3

またからperlop

(ファイル) グロブは、新しいリストを開始するときにのみ、その (埋め込まれた) 引数を評価します。

呼び出すglobとリストが作成され、リスト全体が返されるか (リスト コンテキストの場合)、一度に 1 つの要素が取得されます (スカラー コンテキストの場合)。ただし、 を呼び出すたびglobに個別のリストが作成されます。

于 2010-04-13T22:22:52.590 に答える
0

(Perlのさびた記憶をかき集めて...)の複数の字句インスタンスは<*>globの独立した呼び出しとして扱われると思いますが、whileループでは同じ「インスタンス」を呼び出しています(それが意味するものは何でも)。

たとえば、これを行った場合を想像してみてください。

while (<*>) { ... }
...
while (<*>) { ... }

あなたは確かにそれらの2つの呼び出しが互いに干渉することを期待しないでしょう。

于 2010-04-13T21:58:25.633 に答える