POE::Wheel::ReadLine は便利なのですが日本語が使えません。なので、パッチを書きました。
使い方
利用は自己責任でお願いしますm(_ _)m。
ReadLine-1.003.patchをDLして、ReadLine.pmにあててください。でもって、POE/Wheel/ReadLine/JP.pmをインクルードパスが通ってるとこに置いて下さい*1。
ソース側では、UTF-8でいい場合は、
use POE qw(Wheel::ReadLine::JP);
他の文字コードの時は、
use POE qw(Wheel::ReadLine); use POE::Wheel::ReadLine::JP (charset => 'euc-jp');
等として下さい。
パッチの説明
内部でバイト列を保持していたのを、unicode文字列で保持するように変更しています。伴い、本体側で以下の変更をしました。
"use bytes" を消した
一番ハマったとこかも。こんなプラグマ知らなかったですよ・・・。
全半角の判断
Unicode::EastAsianWidth で文字の印字幅(全角か半角か)取得してます。(→こちらのエントリ参照)
length(_normalize($str)) != _display_width($str)
_normalizeはエスケープ文字とかを可視化する関数で、_display_widthは表示幅を計算する関数です。今までは_normalizeした結果はASCIIだったのでlengthを取れば_display_widthになったのですが、Unicode文字列だと事情が変わります。
例えば、「あ」にlengthをかけると、utf8化されてれば1文字、されてなければ3byteです。でも、_display_widthは表示幅なので2です。
_normalize関数を修正
ord取った時に0xFFを超える文字は消しちゃう仕様だったので、変更。utf8文字だと、0xFF以上返すんですよねー。
フックの作成
日本語化は別モジュールでやりたかったので、本体にはフックだけ入れました。
- $POE::Wheel::ReadLine::charset
- $POE::Wheel::ReadLine::stdin, stdout
- 標準入出力。PerlIO噛ませなければならんので。
- POE::Wheel::ReadLine::_display_bytes()
- 表示幅の取得関数。本体では単なるlengthです。
- POE::Wheel::ReadLine::_read_char()
- キーボードから1byteではなく1文字読み込む関数。本体では単なるReadKey(-1)です。