5

この質問が単純に聞こえる場合は申し訳ありません。私の意図は、この (これらの?) 特定の演算子がどのように機能するかを深く理解することであり、perldocs で満足のいく説明を見つけることができませんでした (おそらくどこかに存在します私の人生のためにそれを見つけてください)

特に、私は知りたいです

a)<>

b)<*>または任意のグロブと

c)<FH>

基本的に類似しているか異なるか、および内部でどのように使用されているか。

これについての洞察を得るために、独自のテスト関数を作成しました (以下に示します)。私はまだ完全に理解していません (私の理解は間違っているかもしれません) が、これが私の結論です:

  • <>
    • スカラー コンテキスト: 読み取り中の「現在のファイル」の次の行を読み取ります (@ARGV で提供)。質問: これは非常に特殊なシナリオのように思えますが、なぜそうなのか、一般化できるのかどうか疑問に思っています。また、読み取られている「現在のファイル」とは何ですか? それはファイルハンドルにありますか?カウンターとは?
    • In List Context: @ARGV 内のすべてのファイルを配列に読み込みます
  • <list of globs>
    • スカラー コンテキスト: グロブに一致する現在のフォルダーで見つかった最初のファイルの名前。質問: なぜ現在のフォルダなのですか? これを変更するにはどうすればよいですか?これを < /home/* > のように変更する唯一の方法はありますか?
    • リスト コンテキスト: 現在のフォルダー内のグロブに一致するすべてのファイル。
  • <FH>変数に割り当てられたときに undef を返すようです。 質問: なぜ undef なのですか? 型はないのですか?FH がベアワード ファイルハンドルでない場合、これは同様に動作しますか?

一般的な質問: 実行中に <> などの値を処理するのは何ですか? スカラー コンテキストでは、何らかの種類の参照が返されるか、またはそれらを割り当てる変数は、その時点で他の非 ref スカラーと同一ですか?

また、順番に割り当てているにもかかわらず、出力が毎回リセットされることにも気付きました。つまり、私がそうするとき、私はそれを想定していたでしょう

$thing_s = <>;
@thing_l = <>;

@thing_lはすでに に受信されているため、最初のアイテムが欠落している可能性があります$thing_s。そうでないのはなぜですか?

テストに使用するコード:

use strict;
use warnings;
use Switch;
use Data::Dumper;

die "Call with a list of files\n" if (@ARGV<1);
my @whats = ('<>','<* .*>','<FH>');
my $thing_s;
my @thing_l;
for my $what(@whats){
    switch($what){
                    case('<>'){
                        $thing_s = <>;
                        @thing_l = <>;
                    }
                    case('<* .*>'){
                            $thing_s = <* .*>;
                            @thing_l = <* .*>;
                    }
                    case('<FH>'){
                            open FH, '<', $ARGV[0];
                            $thing_s = <FH>;
                            @thing_l = <FH>;
                    }

    }
    print "$what in scalar context is: \n".Dumper($thing_s)."\n";
    print "$what in list context is: \n".Dumper(@thing_l)."\n";
}
4

2 に答える 2

12

モノは<>すべてイテレータです。これらの亜種はすべて共通の動作をします。

  • リスト コンテキストで使用すると、残りのすべての要素が返されます。
  • スカラー コンテキストで使用すると、次の要素のみが返されます。
  • スカラー コンテキストで使用されundef、イテレータが使い果たされると戻ります。

whileこれらの最後の 2 つのプロパティにより、ループ内の条件として使用するのに適しています。

で使用できるイテレータには、次の 2 種類があります<>

  • ファイルハンドル。この場合<$fh>は と同等readline $fhです。
  • グロブなので、<* .*>と同等glob '* .*'です。

<>何も含まれていないか、ベアワード、または単純なスカラーのいずれかが含まれている場合、 は readline として解析されます。のように、より複雑な式を埋め込むことができます<{ ... }>

それ以外の場合はすべてグロブとして解析されます。これは、引用符を使用して明示的にすることができます:<"* .*">ただし、実際には明示的に行い、glob代わりに関数を使用する必要があります。

イテレータの状態が保持される場所など、いくつかの詳細が異なります。

  • ファイル ハンドルから読み取る場合、ファイル ハンドルはその反復子の状態を保持します。
  • glob 形式を使用する場合、各 glob 式には独自の状態があります。

別の部分は、イテレータが再起動できるかどうかです:

  • glob は one を返した後に再起動しundefます。
  • ファイルハンドルは、シークによってのみ再開できます。すべての FH がこの操作をサポートしているわけではありません。

でファイル ハンドルが使用されていない場合<>、これはデフォルトで特別なARGVファイル ハンドルになります。の動作<ARGV>は次のとおりです。

  • @ARGVが空の場合、ARGVは ですSTDIN
  • それ以外の場合、 の要素は@ARGVファイル名として扱われます。次の疑似コードが実行されます。

    $ARGV = shift @ARGV;
    open ARGV, $ARGV or die ...; # careful! no open mode is used
    

    $ARGVスカラーはファイル名を保持し、ファイルARGVハンドルはそのファイル ハンドルを保持します。

  • ARGVなるとeof、 の次のファイル@ARGVが開かれます。
  • @ARGVが完全に空の場合にのみ、を<>返すことができundefます。

これは、多くのファイルから読み取るためのトリックとして実際に使用できます。

local @ARGV = qw(foo.txt bar.txt baz.txt);
while (<>) {
  ...;
}
于 2013-09-17T20:28:07.793 に答える
4

<>実行中に およびその他の値を処理するのは何ですか?

Perl コンパイラは非常にコンテキストを認識しており、多くの場合、コード セグメントの複数のあいまいな解釈の中から選択する必要があります。括弧内の内容に応じて、へ<>の呼び出しreadlineまたはへの呼び出しとしてコンパイルされます。glob

スカラー コンテキストでは、何らかの種類の参照が返されるか、またはそれらを割り当てる変数は、その時点で他の非 ref スカラーと同一ですか?

ここで何を尋ねているのか、または a の結果を受け取る変数が<>他の変数とは異なるはずだと思う理由がわかりません。これらは常に単純な文字列値です。 によって返されるファイル名glob、または によって返されるファイル データのいずれかですreadline

<FH>変数に割り当てられたときに undef を返すようです。質問: なぜ undef なのですか? 型はないのですか?FH がベアワード ファイルハンドルでない場合、これは同様に動作しますか?

このフォームはファイルハンドルとして扱わFHれ、ファイルが開いていて eof でない場合、ファイルから次のデータ行を返します。それ以外の場合undefは、有効なものを読み取ることができなかったことを示すために返されます。Perl は型に関して非常に柔軟ですがundef、Ruby の のように独自の型として動作しnilます。演算子FHは、グローバル ファイル ハンドルであっても、型グロブへの参照 (変数を含む) であっても同じように動作します。

于 2013-09-17T20:25:54.253 に答える