2002年11月3日(日) 曇り時々晴れのち雨

なんとなく天気の悪い3連休。予定していた屋根なし倶楽部第二回ミーティングも中止して、ごろごろと…

勉強がてら週末にやりかけていたお仕事用のプログラムを作ってはまっていました。手慣れた人なら小1時間程度で十分書けるのでしょうけど、perlする度にほとんど初心者に戻って一からやり直しの私は、参考書と首っ引きです(^^ゞ

会社に置きっぱなしのラクダ本はPerl 4の時のものなので、昨日やっとPerl 5.6対応の最新版(プログラミングPerl第3版)を買ってきました。うへ〜、最近は2分冊になってやたらページが増えているのねぇ。2冊で1万円もしました(ToT)。

でもって、基礎から忘れているので、引数の扱いとか、配列とかからはまって、夕べはお終い(^^ゞ

今日はなんとか本題に取り掛かるものの、binaryファイルの扱いや little endian やら big endian やら pack やら unpack やら… ではまりまくり。特殊な画像ファイルを読んで、カラー補正して、一般的な画像フォーマットに書き出すのだけど、なにせそれぞれの画像仕様がよく分かっていないので、変換前後のサンプル画像を Emacs の hexl-mode で睨んでパズルのように仕様を謎解きしつつ、コーディングしました(--;

実は途中でImageMagickとかで変換できるかもと寄り道しましたが、とっても特殊な形式(単純だけどね)なので無理でした。

仕様が分からないってのは辛いけど、なんとか最低限の謎解きをして、変換後サンプルにほぼ近い出力を得られるものができました。一番はまったのは unpack して取得した値は、sprintf でキャストしておかないととんでもない値になるって所かなぁ。本には型キャストは「Perlでは不要。あるいは、しようとも思わない」なんて書かれているけど、なぜか要りました。私が誤解しているだけ? それともこれは型キャストっていわないのかしらん???

それからなぜか little endian の signed short int. が unpack できずに困りました。結局、(なぜか)big endian の unsigned short で unpack した後、符号付きに修正する格好悪い処理でつじつまはあったみたいだけど、きっともっとエレガントな解があるのだろうなぁ… ↓格好悪い例

    while(($len = read(IMG, $data, 2)) == 2) {
    $val = unpack("n", $data);
    $val = sprintf("%d", $val);
    if ($val > 0x7fff) {$val = $val - 0x10000;}
    …
    

「できた!!」と思っていたら、DOS窓ではシェルが引数を glob してくれないのに気付きました。またまた基本を調べて、<@ARGV> とか glob(@ARGV) とかすればOKと分かりました。(ここまで、EmacsのShellモード上のtcshで確認してたので、tcshが引数を展開してくれていた)

絶対必要なプログラムな訳ではないのですが、Perlを練習するいい機会と思って、休日を捧げました。でも、また暫くすると初心者に戻っちゃうんだよなぁ、これが。

明日は入荷の連絡があった、カーナビのバージョンアップDVDを取りに行かなくちゃ。(ここだけロドスタ日記(^^ゞ)

なんだか夜更かししちゃったなぁ@27:30