Perl 5.11.5 features

Perlの開発版である5.11系列の最新版がリリースされた。

今回もバグフィクス中心なので,特に列挙すべき新機能はない。組み込みファイルハンドルのクラスが修正されたのが唯一の大きな変更か。
5.11.5までは,組み込みファイルハンドルのクラスは不定だったのだが,5.11.5からは常にIO::HandleとIO::Seekableをスーパークラスとして持つIO::Fileとなる。

不定というの心もとないが,実際に不定だったのだから仕方がない。これは,以下のスクリプトを実行してみるとよくわかる。

#!perl -w
use strict;
use IO::Handle;
open my $io, '<', $0; # open the script
while(my $line = $io->getline){
    print $line;
}
sub foo {
    require FileHandle;
    # 何かする...
}
__END__

結果:

$ perl io.pl
Can't locate object method "getline" via package "FileHandle" at io.pl line 7.

このようなケースでは予想に反して異常終了する。しかし,require FileHandle;の行をコメントアウトすると,予想通りスクリプト自身を出力するquineとなる。
これは,PerlがFileHandleパッケージの有無でファイルハンドルのクラスを切り替えているためだ。通常,FileHandleはuseで読み込むので,その場合に問題となることは少ない。しかし,FileHandleとIO::Handleの持つメソッドは微妙に異なり,それが問題になることもある。クラスの切り替えそのものは古いPerlとの互換性のためにこのようになっていたのだが,それで挙動がおかしくなるのも困る。これが,今回のリリースでは常にIO::Fileにブレスされるようになったということだ。
なお,今回の修正は本当は常にIO::Handleにブレスされる予定だったのだが,これでは逆にFileHandleにブレスされることを期待したアプリケーション*1が動かなくなってしまい,結局IO::Fileのクラス階層をperlコアで設定したうえでIO::Fileにブレスされることになったようだ。これなら互換性を壊すこともなく,妥当である。

See also perl5115delta.

過去の記録:

*1:たとえば,Plack