2007-04-20

utf8文字列のファイル名の扱いはどうなってるんでしょう?

 気が利いているPerlのことですから、utf8文字列*1でopenすればファイルシステムに適切な形で扱われるものだと思いきや、そのままファイル名として扱われるっぽい。

 えーっ。Perlのくせに気が利いてないなぁ。入出力ストリームに対しては:encoding()等でフィルタリングしてくれるくせに。

 やっぱさあ、utf8文字列をファイル名として渡したら、適当に変換して欲しいじゃん。まあPerl様が自分で変換するのがイヤだって言うのなら、自分で変換処理を書くからそれを指定させてくれよ、と思うわけ。

 ――というわけで、きっと誰かが既に作ってそうなので、どのモジュールなのかご存じの方がいましたら教えてくださいな。自分で書くのは面倒なので*2

 そもそもこういうのやりたいときはどーするんでしょ。CORE::openをフックするとか?*3

追記

 もしそんなのがあるとすればfilenameプラグマとかで

# CP932に変換する
use filename 'cp932';
use filename ':encoding(cp932)';

# convert()で変換する
use filename \&convert;
sub convert {
  my $utf8_filename = shift;
  my $encode_filename = Encode::encode('cp932', $utf8_filename);
  return $encode_filename;
}

use utf8;
open my $fh, '<', '日本語ファイル名.txt';
...

――とかになるのかな。いや、ディレクトリ名も含まれるべきだから、ちょっと違うかもしれない。

 おそらくはブロックローカルにすべきなんだろうけれど。自作するんならやりかた知らないしなぁ。

名称はfilenameプラグマでいいのか?

 まかまかさんのアドバイスでなんとかなりそうな予感。CORE::*じゃなくてCORE::GLOBAL::*ね。

 CPANで検索かけてpodも見つけた。

http://search.cpan.org/~nwclark/perl-5.8.8/pod/perlsub.pod#Overriding_Built-in_Functions____

 でまあ、まじめにやると

  • open()、opendir()でutf8文字列の時に変換する
  • readdir()、glob()ではutf8文字列に変換する

必要があるわけで。

 他にもあるかな?

 あとはスコープの設定かー。encodingもスコープ関係ないんで同じでいいか。。。

*1:utf8フラグ付きの文字列ね。以下同じ。

*2:標準でそういう動作にすべきだ、とは思うけれど。

*3:できるんだっけ?