今日、この奇妙なコード行を入手しました。CWD に項目 (.
と以外..
) があるかどうかに応じて、「空」または「空ではない」と表示されます。
意味がわからないので仕組みを知りたいです。
perl -le 'print+(q=not =)[2==(()=<.* *>)].empty'
私が興味を持っているビットはです<.* *>
。ディレクトリ内のすべてのファイルの名前を取得する方法がわかりません。
ゴルフのワンライナーです。-e
フラグは、コマンドラインの残りの部分をプログラムとして実行することを意味します。は-l
、自動ラインエンド処理を有効にします。
この<.* *>
部分は、展開する2つのパターンを含むグロブです:.*
と*
。
この部分
(q=not =)
単一の値(文字列「not」)を含むリストです。これq=...=
は代替の文字列区切り文字であり、ワンライナーを引用するために単一引用符が使用されているために使用されているようです。
その[...]
部分は、そのリストの添え字です。下付き文字の値は、この比較の結果に応じて、0(値 "not")または1(nothing、空の文字列として出力)のいずれかになります。
2 == (()=<.* *>)
ここではたくさんのことが起こっています。比較では、グロブが正確に2つのアイテムのリストを返したかどうかをテストします(とと仮定.
)..
が、それをどのように行うかは注意が必要です。内側の括弧は空のリストを示します。このリストに割り当てると、globがリストコンテキストに配置され、ディレクトリ内のすべてのファイルが返されます。(スカラーコンテキストでは、イテレータのように動作し、一度に1つだけを返します。)割り当て自体はスカラーコンテキスト(比較の右側にある)で評価されるため、割り当てられた要素の数を返します。
主要な+
点は、Perlがリストを引数として解析しないようにすることprint
です。末尾.empty
は、文字列「empty」をリストから出てきたもの(つまり、「not」または空の文字列)に連結します。
<.* *>
は 2 つのパターンからなるグロブです:.*
すべてのファイルで始まり、すべてのファイル.
に*
対応するすべてのファイル名です (これは通常の DOS/Windows の規則とは異なります)。
(()=<.* *>)
リストコンテキストでグロブを評価し、一致するすべてのファイル名を返します。
次に、 との比較により2
、それがスカラー コンテキストに置かれるため2
、返されたファイルの数と比較されます。その番号が2
の場合、ディレクトリ エントリは.
と..
、ピリオドだけです。;-)
<.* *>
を意味し(glob(".*"), glob("*"))
ます。 glob
シェルと同じ方法でファイル パターンを展開します。
その機能のドキュメントはこちらです。(セクションの終わり近くをスクロールします)