3

Windows *.csv はコマンドラインから @ARGV に展開されないため、通常、次のようなことを行うことになります

map { glob } @ARGVファイル名を取得します。

しかし、私は異常に遭遇し、実際に何が起こっているのかを理解したいと思っていました. 「ストレンジャー・イン・ア・ストレンジ・ランド」を読み終えたばかりなので、完全に理解していないと言えます!

use Modern::Perl;

# gets the filelist but then warns
say "Test 1 ", '-' x 20;
do { func($_) for map { glob } @ARGV } or warn "at least one arg expected\n";
say '-' x 27, "\n";

# works ok
say "Test 2 ", '-' x 20;
my @x = map { glob } @ARGV or warn "at least one arg expected\n";
func($_) for @x;
say '-' x 27, "\n";

# prints 2 (there are two files)
say "Test 3 ", '-' x 20;
func($_) for (map { glob } @ARGV or warn "at least one arg expected\n");
say '-' x 27, "\n";

sub func { 
  say "in func = $_[0]";
}

出力:

Test 1 --------------------
in func = t.csv
in func = t2.csv
at least one arg expected
---------------------------

Test 2 --------------------
in func = t.csv
in func = t2.csv
---------------------------

Test 3 --------------------
in func = 2
---------------------------

テスト 1:なぜ が true を返さないのか理解できdoません。何かが出力された場合に true を返すfunc最後のステートメントを返します。sayそれともforへの戻りとして使用されるのはdoですか?

テスト 3:明らかにスカラー コンテキストが暗示されていますが、どのように? マップの周りに括弧を使用しましたか?

ありがとう、リチャード。

4

2 に答える 2

3

テスト1

for最初のケースは、ステートメント修飾子が原因でfalse(無効と思われる場合があります)を評価する場合です。観察:

  DB<1> x do { func($_) for map { glob } @ARGV }
in func = t.csv
in func = t2.csv
0  ''
  DB<2> x do { func 't.csv' ; func 't2.csv' }
in func = t.csv
in func = t2.csv
0  1

これはステートメント修飾子であり、式修飾子ではないことに注意してください。この区別を行う言語では、式には戻り値がありますが、ステートメントはありません。

Perlはそのような言語です。単純なプログラムを考えると

#! perl
@a = (1 for 6, 7, 8);

実行しようとすると、構文エラーで失敗します。

foo行2の構文エラー「1for」の近く
コンパイルエラーのため、fooの実行が中止されました。

あなたは最初のテストであなたの意図をより直接的に表現するかもしれません

map func($_), map glob, @ARGV or warn "at least one arg expected\n";

期待される出力を提供します。

テスト1--------------------
func=t.csvで
func=t2.csvで
---------------------------

テスト3

3番目のケースでは、 Perlの論理和が機能するように定義されているため、スカラーコンテキストを取得します。

Cスタイルの論理和

バイナリ||は、短絡論理OR演算を実行します。つまり、左のオペランドがtrueの場合、右のオペランドも評価されません。スカラーまたはリストコンテキストは、評価されると右のオペランドに伝播します。

左側のオペランドは、常にバイナリ(スカラー)コンテキストで評価されます。式全体のコンテキストは、右のオペランドにのみ代入されます。

于 2012-06-07T13:56:54.647 に答える
2

シンプルに保ち、実用的でポータブルなソリューションを投稿します。


テスト 1

の結果を確認していますdo

forこれは、 によって評価された最後の操作の結果でありdofor有用なものは何も返しません。


テスト 2

リスト割り当ての結果を確認しています。

スカラー コンテキストでのリスト代入は、右辺 ( map) によって返されるスカラーの数を評価します。


テスト 3

によって返された値を繰り返し処理していますor

orは、その LHS (スカラー コンテキストで評価される) またはその RHS のいずれかを返します。これはmap、スカラー コンテキストで評価されたによって返される値 (数値) またはによって返される値warn(ブール値) になります。


opsがリストと数値の両方を同時に返すことを望んでいます。それはうまくいきません。

bsd_globそうしないと、スペースを含むパスが壊れてしまうことに注意してください。(glob実際にはbsd_glob! の内臓を使用します)

use File::Glob qw( bsd_glob );
@ARGV = map bsd_glob($_), @ARGV if $^O eq 'MSWin32';
die if @ARGV < 2;
func($_) for @ARGV;
于 2012-06-07T15:05:46.690 に答える