綾小路龍之介の素人思考

Jcode.pmで出力文字コードを引数で渡せないというのは本当か。

多分、半分本当で半分嘘だと思う。無料版iswebはJcode.pmを標準で実装していないので(Jcodeは設置済みでした(Jcode.pm v2.06)。use Jcode;で使えます。)Jcode.pm0.88をおいて実験してみたところ、次のようなことがわかった。1、出力文字コードは文字列または文字列を内容として持つスカラ変数で渡さねばならない。2、配列要素として渡すとエラーが生じる。つまり、下のように書いた場合は思ったとおりの結果が得られる。

my $str = '文字コード変換テスト';
my $OutCode = 'utf8';
print Jcode->new($str)->h2z->$OutCode;

ただし、次のように書いた場合は思い通りの結果が得られない($strをutf8に変換してくれない。)。エラーが生じる。

my $str = '文字コード変換テスト';
my $OutCode[0] = 'utf8';
print Jcode->new($str)->h2z->$OutCode[0];

例えば、引数を2つ要求する文字コード変換プログラムで、第1引数に変改対象のファイル名、第2引数に出力文字コード、がセットされているとする。このとき、下のようなコードを書いてみると上手くいかない。最初のセクションは引数の存在チェックと存在しない場合の初期値の設定である。第1引数がセットされていればこれを変換対象のファイルとし、そうでない場合は自分自身。第2引数がセットされていればこれを出力文字コードとし、そうでない場合はutf8。2番目のセクションで変換対象ファイルからデータをもらい$strに格納。3番目のセクションで文字コード変換を行って出力。

$ARGV[0] = defined $ARGV[0] ? $ARGV[0] : $0;
$ARGV[1] = defined $ARGV[1] ? $ARGV[1] : 'utf8';
open IN,$ARGV[0];
my $str = join'',<IN>;
close IN;
print "Content-Type: text/html\n\n";
print Jcode->new($str)->h2z->$ARGV[1];

この場合最後の行でエラーが生じる。これを回避するには前述のようにutf8などの出力文字コードを含む変数をスカラ変数として、配列要素とすることが肝心である。例えば以下のように書き換えれば思ったとおりに動く。これの欠点をあげるとするならば、メモリ上に余分な変数を作ることだろう。たった1回しか使わない$codeを全く同じ内容をもつ$ARGV[1]のコピーとしてわざわざ再定義するは、無駄なメモリを消費することにはならないのだろうか。

my $name = defined $ARGV[0] ? $ARGV[0] : $0;
my $code = defined $ARGV[1] ? $ARGV[1] : 'utf8';
open IN,$name;
my $str = join'',<IN>;
close IN;
print "Content-Type: text/html\n\n";
print Jcode->new($str)->h2z->$code;

Jcode.pmが内部でどのように動いているかはよく知らないが、少なくとも上で述べた問題を解決する策を一つ知っている。それはjcode.plで使われていたインターフェイスを使うことだ。例えば下のように。すると自分で定義した変数は$strだけとなり、メモリを余分に消費することもないと思う(もちろん引数に何が含まれているかを覚えておかねばならないが。)。

$ARGV[0] = defined $ARGV[0] ? $ARGV[0] : $0;
$ARGV[1] = defined $ARGV[1] ? $ARGV[1] : 'utf8';
open IN,$ARGV[0];
my $str = join'',<IN>;
close IN;
print "Content-Type: text/html\n\n";
print Jcode::convert(\$str, $ARGV[1]);

ソーシャルブックマーク

  1. はてなブックマーク
  2. Google Bookmarks
  3. del.icio.us

ChangeLog

  1. Posted: 2008-01-15T21:51:59+09:00
  2. Modified: 2008-01-15T05:23:35+09:00
  3. Generated: 2017-01-16T23:09:19+09:00