彼らがあなたにPerlを教えているのなら、彼らは最新のPerl構文を使うだろうと思うでしょう。これを個人的に服用しないでください。結局のところ、これはあなたが教えられた方法です。ただし、新しいPerlプログラミングスタイルを知っておく必要があります。これは、あらゆる種類のプログラミングミスを排除し、コードを理解しやすくするためです。
- プラグマ
use strict;とuse warnings;を使用します。警告プラグマは-w、コマンドラインのフラグの必要性を置き換えます。実際には、より柔軟で優れています。たとえば、問題になることがわかっている場合は、特定の警告をオフにすることができます。use strict;プラグマでは、myまたはourのいずれかを使用して変数を宣言する必要があります。(注:Perl組み込み変数を宣言しないでください)。99%の時間、あなたは私のを使用します。これらの変数は字句スコープと呼ばれますが、真のローカル変数と考えることができます。字句スコープの変数には、スコープ外の値はありません。たとえばmy、whileループ内を使用して変数を宣言した場合、その変数はループが終了すると消えます。
openステートメントには3つのパラメーター構文を使用します。以下の例では、3つのパラメーター構文を使用します。このように、ファイルが呼び出された場合>myfile、私はそのファイルから読み取ることができます。
- **ローカルで定義されたファイルハンドルを使用します。
my $file_1_fh単にFILE_1_HANDLEの代わりに使用することに注意してください。古い方法であるFILE_1_HANDLEはグローバルスコープであり、さらにファイルハンドルを関数に渡すことは非常に困難です。字句スコープのファイルハンドルを使用すると、うまく機能します。
orandandの代わりに||andを使用する&&:理解しやすく、演算子の優先順位が優れています。それらは問題を引き起こさない可能性が高いです。
openステートメントが機能したかどうかを常に確認してくださいopen:ステートメントが実際にファイルを開いたことを確認する必要があります。またはuse autodie;、ステートメントが失敗した場合にプログラムを強制終了するプラグマを使用しますopen(これはおそらくとにかくやりたいことです。
そして、これがあなたのプログラムです:
#! /usr/bin/env perl
#
use strict;
use warnings;
use autodie;
open my $file_1, "<", shift;
open my $file_2, "<", shift;
open my $output_fh, ">", shift;
for (;;) {
my $line_1 = <$file_1>;
my $line_2 = <$file_2>;
last if not defined $line_1 and not defined $line_2;
no warnings qw(uninitialized);
print {$output_fh} $line_1 . $line_2;
use warnings;
}
上記の例では、空であっても両方のファイルから読み取ります。読むものがない場合、$line_1または$line_2は単に未定義です。$line_1読んだ後、と$line_2が未定義かどうかを確認します。もしそうなら、私はlast私のループを終了するために使用します。
私のファイルハンドルはスカラー変数なので、中かっこで囲むのが好きです。そのため、印刷したい変数ではなく、ファイルハンドルであることがわかります。私はそれを必要としませんが、それは明快さを改善します。
に注意してno warnings qw(uninitialized);ください。これにより、初期化されていない警告がオフになります。$line_1またはが初期化されていない可能性があることを知っている$line_3ので、警告は必要ありません。これは貴重な警告であるため、印刷ステートメントのすぐ下でオンに戻します。
forそのループを行う別の方法は次のとおりです。
while ( 1 ) {
my $line_1 = <$file_1>;
my $line_2 = <$file_2>;
last if not defined $line_1 and not defined $line_2;
print {$output_fh} $line_1 if defined $line_1;
print {$output_fh} $line_2 if defined $line_2;
}
無限ループは、forループではなくwhileループです。一部の人々はCスタイルのforループが好きではなく、コーディング慣行からそれを禁止しています。したがって、無限ループがある場合は、を使用しますwhile ( 1 ) {。私にとって、おそらく私がCのバックグラウンドから来たため、無限ループfor (;;) {を意味し、消化するのに数ミリ秒余分にかかります。while ( 1 ) {
また、印刷する前に$line_1、または$line_2が定義されているかどうかを確認します。no warningandを使用するよりはましだと思いますwarningが、1つにまとめるのではなく、2つの別々のprintステートメントが必要です。