Perlのエラーメッセージのコーナー。
Perlのエラーメッセージが表示される最小のプログラムを書いて、どういうときにどう怒られるかを研究する。
今回のお題は
-T and -B not implemented on filehandles

である。
※今回スッキリしません!

Door Handle...
これは「-T and B」と「not implemented on filehandles」の間に「are」が省略された受動態のSVC文で、「ファイルハンドルでは-Tと-Bはサポートされていない」という意味になる。

これらはファイルテスト演算子と呼ばれるPerlの便利機能の一種で、ファイル名に対しては便利に使える。

-Tは右に来る式がテキストファイルであれば真を、そうでなければ偽を返す。
-Bは逆に、右に来る式がバイナリーファイルであれば真を、そうでなければ偽を返す。

テキストファイルというのはPerlのスクリプトやHTMLファイル、Cのソースコードのように、最初から最後まで文字コードが入っているものである。
一方バイナリーファイルというのは画像や音声、コンパイルされたプログラムの実行形式のように、文字コード以外のビットが入っているものである。
もとより文字コードもビット(2進数値)のかたまりであるから、テキストはバイナリーの一種であるような気もするが、テキストでないものをバイナリーファイル、というように呼び習わしている。
人間は動物の一種であるが、「君は人間だろう。動物じゃないんだから行儀よくしなさい」などと言うのと同じである。
この話10回ぐらい書いた気がする。

プログラムを書いて実行してみる。
#! /usr/bin/perl
#
# fileTestTest.pl -- ファイルテスト演算子で遊ぼう!

use 5.010;
use strict;
use warnings;
use strict;
use warnings;

my $fname = shift;

if (-T $fname) {
say "$fname should be the text file";
} else {
say "$fname should not be the text file";
}

if (-B $fname) {
say "$fname should be the binary file";
} else {
say "$fname should not be the binary file";
}

say "The size of $fname is ", -s $fname;
実行してみる。
[perl]$ ./fileTestTest.pl ./fileTestTest.pl
./fileTestTest.pl should be the text file
./fileTestTest.pl should not be the binary file
The size of ./fileTestTest.pl is 451

[perl]$ ./fileTestTest.pl /usr/bin/perl
/usr/bin/perl5.16 should not be the text file
/usr/bin/perl5.16 should be the binary file
The size of /usr/bin/perl5.16 is 35440
PerlのスクリプトfileTestTest.plに対し、-Tは真を、-Bは偽を返す。
なお-sはサイズをバイトで返す演算子であって、451を返す。

一方、Perlのエンジン/usr/bin/perlに対し、-Tは偽を、-Bは真を返す。
なお-sは35440を返す。
ここまではうまくいっているように思える。

では、演算子にファイル名ではなくファイルハンドルを渡したらどうなるだろうか。
これが今回の主題である。
早速変えてみる。
#! /usr/bin/perl
#
# fileTestTest.pl -- ファイルテスト演算子で遊ぼう!

use 5.010;
use strict;
use warnings;
use strict;
use warnings;

my $fname = shift;

open my $fhandle, "<", $fname;

if (-T $fhandle) {
say "$fname should be the text file";
} else {
say "$fname should not be the text file";
}

if (-B $fhandle) {
say "$fname should be the binary file";
} else {
say "$fname should not be the binary file";
}

say "The size of $fname is ", -s $fhandle;

close $fhandle;
では実行。
[perl]$ ./fileTestTest.pl ./fileTestTest.pl
./fileTestTest.pl should be the text file
./fileTestTest.pl should not be the binary file
The size of ./fileTestTest.pl is 506 # ファイルサイズが増えている

[perl]$ ./fileTestTest.pl /usr/bin/perl
/usr/bin/perl5.16 should not be the text file
/usr/bin/perl5.16 should be the binary file
The size of /usr/bin/perl5.16 is 35440
あれ、なんかできたなー。。
Perlのバージョンが変わって、ある日できるようになったんだろうか。
それともぼくがなんかカンチガイしているのだろうか。
わからない。

このブログたまにこういうことがあるが、わからないままに放置する。
分かったら報告するので許して下さい。
スミマセン。
分かる人は教えて下さい!



ところで、-Tおよび-B演算子は、Unicodeについてもサポートしているのだろうか。
試してみる。
いま、ぼくのMacのターミナルはUTF-8に設定されている。
(購入時の設定)
[perl]$ cat >> utf8.txt
日本語
日本語
このファイルはUTF-8であってしかるべきだ

[perl]$ cat utf8.txt
日本語
日本語
このファイルはUTF-8であってしかるべきだ

[perl]$ ./fileTestTest.pl utf8.txt
utf8.txt should be the text file
utf8.txt should not be the binary file
The size of utf8.txt is 77
ということで、UTF-8はOKっぽい。
[perl]$ iconv -f UTF-8 -t UTF-16 < utf8.txt > utf16.txt

[perl]$ ./fileTestTest.pl utf16.txt
utf16.txt should not be the text file
utf16.txt should be the binary file
The size of utf16.txt is 64
ということで、UTF-16はダメっぽい。
まあそうか。