ROUTE 3390

備忘録的な用途で書いていますが、どなたかの役に立つ事があれば嬉しいです。

ファイルハンドラをむやみに利用しない

perlでのファイル操作ってどうやるのかなって調べると、下記のようなコーディングで説明されている事があります。

my $file_name = 'test.txt';
open(FILE, $file_name);
while(<FILE>) {
    print;
}
close FILE;

このFILEというのはファイルハンドラと呼ばれます。
ファイルハンドラは指定したファイルをハンドル(操作)するものです。
上記の例では、と記述する事で「test.txtの標準入力を取得」という命令に、
close FILE と記述すれば「test.txtを手放す」という命令が出来ます。

少し別の表現を使うと
「FILEという名前のグローバルな変数に型グロブを格納」しています。

型グロブについての詳細な説明は省きますが、同じ名前を持つ $スカラや@配列、%ハッシュをまとめたものです。
※いずれちゃんと説明出来るようになりたいです。

open関数は第一引数に未定義のスカラー変数を渡す事で、「型グロブ」ではなくて「型グロブへのリファレンス」を返してくれるようになります。

結果からいうと下記のように書けます。

my $file_name = 'test.txt';
open(my $fh, $file_name);
while(<$fh>) {
    print;
}
close $fh;

このようにファイルハンドラを使わなくても下記のように記述する事が出来ます。(古いバージョンだと出来ないらしい)
$fhはmy宣言しているため、ファイルハンドラを利用するより副作用の無い安全なコードになりますよね。



余談ですが、openとcloseはセットで書いたほうがいいです。
connectやdisconnectなんかにも言えますが、忘れずにセットで記述しなくてはいけない処理は下記のように関数を渡すようにコーディングすればシンプルかもですね!

sub file_open_close{
  my ($reading_method, $file_name) @_;
  open(my $fh, $file_name);
  $reading_method->($fh);
  close $fh;
}

file_open_close(
  sub{
    my ($fh) = @_;
    while(<$fh>) {
      print;
    }
  }, $file_name
);