perl tie encode decode についての戦い
ネットのどこ探しても見つからなかったので書いておきたい。(完結編はこちら)
perlを使ったwebアプリの開発中である。
tieでファイルのデータの読み書きを行っていた。
tieで関連付けたファイルから文字列を取ってshift-jisに書き出すところでつまずいた。
foreachで変数をdecodeしながらループしてターゲットの配列に入れて行く。
ターゲットの配列をループして書き出しの変数に入れて、出来上がったところで変数をencodeして書き出す。
tieは外部のファイルを紐つけるけど、内部ではなんらdecordeをしていないのだなあ。
何かオプションが有るのだろうか。
考えないで回すとutf8になるから、今まで気にしなかった。
もっと考えたいのだが、時間がない。
use Encode; use Encode 'encode'; use utf8 ();##### 文字列のutf8として扱う為のモジュール ######メインルーチンの頭で宣言している my @tagfile=@$down_file_ref;# my $val_write=""; foreach my $rec (@tagfile){ $rec = decode("UTF-8",$rec); my $record=""; my ($meigi)=$rec=~m[j_b_mei>(.*?)$val_write = encode('Shift_JIS',$val_write); my $filename = $main::path{k_path}."csv.down"; unlink $filename; open(DATA, ">>", $filename); print DATA $val_write;
412741
考えてみれば、どんな変換でも、fromとtoがなければ出来ない。
従来の変換の考え方は一回のコマンドでその両方をする形だったと思う。
"UTF-8" to 'Shift_JIS' というようなパラメータの渡し方である。
しかしこれでは一回の処理の中で、一つの外部から取り込んだ文字列を2−3の複数のエンコードの書きだす時に混乱する。なので、decodeと言うコマンドで、一回中立のエンコードに変換して、encodeと言うコマンドでそれを書き出すのである。
問題は配列を一括してdecodeやencodeできるかという事だった。
残念ながら、できなかった。
また、僕はファイルの読み書きにtie (ファイルとperl上の配列を同じものとして扱える)を使っている。
問題はtieした配列のloop変数をどう取り扱うことがいいのか、分からなかったことである。
tieで関連付けられた配列をforeachの中で変更すると即座にファイルの中の値が変わってしまう。
元がsjisのファイルとutf8のファイルを開けて、片方の値をもう一方に付け加(hashとか利用して)えていくような処理の場合複雑になる。
当初は別なルーチンでファイルとtieした配列のレファレンスを直接回していたが、問題が多かった。
今はtieした配列をそのまま別な配列にコピーしてそちらをいじることにした。
$rec = decode("UTF-8",$rec);
これは、外部から取り込んだファイルの文字列がUTF-8であるということを宣言している。
大事なことは、元のファイルのエンコードを書くことである。
$val_write = encode('Shift_JIS',$val_write);
これは書きだすファイルのエンコードを指定している。
色々と研究などを含めて6時間かかった(夜食うたた寝込み)。
前に理解していたのだったけど、もう2年位前のことだから忘れてしまった。
ファイルがsjisで書き出せた時は超嬉しかったのである。
あの快感は、何者にも変えがたい。
413356