1

私は問題があります。このperlプログラムは、すべてのファイルを開いてそれらを一緒にマップする必要があります。これは、UNIXシステムでコマンドを貼り付けるのと似ています。

my @files;
for (@fileList ? @fileList : qw(-)) {
open  $files[@files], '<', $_; #}
}
while (grep defined, (my @lines = map {scalar <$_>;} @files)) {
    chomp @lines;
    print join("\t", @lines), "\n";
}

問題は、次のような2つの異なるファイルになると

One 
Two 
Three

と:

Apple
Banana
Orange
Kiwi

初期化されていない値のエラーがスローされます。

Use of uninitialized value $lines[0] in chomp 
Use of uninitialized value $lines[0] in join 

また、ファイルがApple、Banana..およびOne2 3の場合、同じエラーが発生します。

前もって感謝します

4

2 に答える 2

3

問題は、ファイルの長さが異なるため、@lines配列に未定義の値が含まれることです。while条件ではフィルターで除外できませんが、後でループ内でフィルターで除外できます。

while (grep defined, (my @lines = map {scalar <$_>;} @files)) {
    @lines = map defined($_) ? $_ : "", @lines;

これにより、未定義の値が空の文字列に置き換えuninitializedられ、タブが正しく配置されたまま、これらの値に対する警告が削除されます。

undef空の文字列に文字列化されるため、コードは実際に意図したとおりに動作することに注意してください。警告があるからこそ、警告が表示されます。ただし、警告をオンにしておくことをお勧めします。これにより、このようなエラーを見つけて適切に修正できます。

open失敗したケースを明示的に処理しない限り、戻り値をチェックせずに使用することはお勧めできません。適切な方法はこれを行うことです:

open $files[@files], '<', $_ or die $!;

簡単にするために、

use autodie;

モジュールは、autodieなどの重要な関数呼び出しに対して致命的なエラーを生成しopenます。

于 2012-12-16T18:38:42.937 に答える
0

Perl v5.10以降がインストールされている場合(そして、現在5年経過しているので、実際にインストールする必要があります)、(defined-or)演算子を使用して、ファイルの終了後に//null文字列を置き換えることができます。undefまた、オペランドにスカラーコンテキストを課すため、演算子を使用する必要はありませんscalar。さらに、の代わりにlength演算子を使用する必要がありますdefined。その結果、このコードになります。

while (grep length, (my @lines = map { <$_> // '' } @files)) {
    chomp @lines;
    print join("\t", @lines), "\n";
}
于 2012-12-17T22:12:09.063 に答える