2009/04/14(火)続・UOA ベンダーエージェントの(略

このために UOA 買ったぜ!ベンダーエージェントの使い方以外よくわかんねぇ。
サンプルデータを用意して、パーサーを書いた。バンダナのローカライズにも対応した。
これで行けそうだ。が、コードが凄く汚いので直す必要あり、でも疲れたので暫くやらない。

サンプルデータ:
Bulk Order Deed Blessed 重量: 1 大口 Spined Leather 高品質 個数: 15 leather skirt: 15 leather bustier: 0 leather shorts: 0 female leather armor: 0 studded bustier: 0 studded armor: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Spined Leather 高品質 個数: 15 female leather armor: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Barbed Leather 標準 個数: 15 studded gorget: 15 studded gloves: 15 studded sleeves: 15 studded leggings: 15 studded tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Horned Leather 高品質 個数: 10 studded leggings: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Horned Leather 標準 個数: 15 leather skirt: 0 leather bustier: 0 leather shorts: 0 female leather armor: 0 studded bustier: 0 studded armor: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Barbed Leather 高品質 個数: 15 leather cap: 0 leather gorget: 0 leather gloves: 0 leather sleeves: 0 leather leggings: 0 leather tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Agapite Ingot 高品質 個数: 20 platemail gorget: 0 platemail gloves: 0 plate helm: 0 platemail arms: 0 platemail legs: 0 platemail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Agapite Ingot 高品質 個数: 20 chainmail coif: 0 chainmail leggings: 0 chainmail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Barbed Leather 標準 個数: 20 bone armor: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Dull Copper Ingot 高品質 個数: 20 chainmail coif: 0 chainmail leggings: 0 chainmail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Shadow Iron Ingot 標準 個数: 20 chainmail coif: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Shadow Iron Ingot 標準 個数: 15 ringmail leggings: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Verite Ingot 高品質 個数: 20 ringmail gloves: 0 ringmail sleeves: 0 ringmail leggings: 0 ringmail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Dull Copper Ingot 高品質 個数: 20 platemail legs: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 iron ingots 高品質 個数: 20 platemail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 Dull Copper Ingot 高品質 個数: 10 plate helm: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 cloth 高品質 個数: 20 kilt: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 cloth 高品質 個数: 20 バンダナ: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 cloth 標準 個数: 20 バンダナ: 20 shirt: 20 skirt: 20 thigh boots: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 大口 Copper Ingot 標準 個数: 20 chainmail coif: 0 chainmail leggings: 0 chainmail tunic: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 iron ingots 高品質 個数: 20 ringmail gloves: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 iron ingots 高品質 個数: 20 ringmail leggings: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 iron ingots 高品質 個数: 20 ringmail leggings: 0, 価格: --
Bulk Order Deed Blessed 重量: 1 小口 iron ingots 高品質 個数: 20 ringmail sleeves: 0, 価格: --
出力:
出力内容は、素材-ブツ-品質-数 で、これが内部のハッシュDB のキー名になる。ブツのスペースはアンダースコアに変換してある。
spined-leather_female_large-HQ-15
spined-female_leather_armor-HQ-15
barbed-studded_large-NQ-15
horned-studded_leggings-HQ-10
horned-leather_female_large-NQ-15
barbed-leather_male_large-HQ-15
agapite-plate_large-HQ-20
agapite-chain_large-HQ-20
barbed-bone_armor-NQ-20
dull_copper-chain_large-HQ-20
shadow_iron-chainmail_coif-NQ-20
shadow_iron-ringmail_leggings-NQ-15
verite-ring_large-HQ-20
dull_copper-platemail_legs-HQ-20
iron-platemail_tunic-HQ-20
dull_copper-plate_helm-HQ-10
iron-fences_large-HQ-15
shadow_iron-tear_kite_shield-NQ-10
leather-leather_male_large-HQ-20
leather-studded_armor-HQ-15
cloth-kilt-HQ-20
cloth-bandana-HQ-20
cloth-girl_large-NQ-20
copper-chain_large-NQ-20
iron-ringmail_gloves-HQ-20
iron-ringmail_leggings-HQ-20
iron-ringmail_leggings-HQ-20
iron-ringmail_sleeves-HQ-20
ここまで整形すれば、この形のデータを処理する機能はすでに付いてるので後は本体にマージするだけ。

しっかし、コンピュータが処理するのに優しくないデータを処理するといろいろ例外的な処理が必要になって無駄にコードが増える。そうすると、
  • 気持ち的にすごい疲れる
  • 後の仕様変更やローカライズによるデータの変化の可能性を考えると戦々恐々
で、現状の汚いコードだとデータが変わった時の修正箇所がワケワカメ。


確認中に既存のスクリプトにバグが2個見つかりました。
  • ringmail glove がありませんでした。
  • plate helm が platemail helm になっていました。
直していません。

2009/04/10(金)BOD管理CGI Ver1.1

Ver.1.1 にしました。
  • パスワード変更機能の追加
  • BOD管理CGIについて の下の方にリストアップしてあるもののうち、ただのバグであり実装されている必要があるものを実装
  • 静的ファイルのモジュール化
    • 管理者ツールと共有するデータがあったのですごい楽になりました。俺が。
しました。

バグが見つからなければ、次の Ver.1.2 では 「UOA のベンダーエージェントのクリップボード情報をコピペして一括登録できる機能」(長ぇ)が追加機能として入る予定です。
この機能は、[既存のデータに追加]/[既存のデータを上書き] と動作を選べるとうれしいのかなぁ。と考えつつ追記のみで作る予定。
ローカライズにより「バンダナ」とか超ウザいんですが、まぁ頭を使わない無駄に長いコードで対応するだけなんで淡々と進めます。

こっちのスペースに持ってくる際にコードを書き直したおかげで
  • きっと細工ルニックにも楽しく対応できるはず。
  • きっとローカライズにも苦々しくも対応できるはず。

2009/04/09(木)UOA のベンダーエージェント機能のクリップボードデータ

UOA のベンダーエージェント情報をパース?トークナイズ?するコードだけ試しに書いてみた。
プログラムっていうよりただの正規表現で、ぶっちゃけ俺は何もしてない。
あくまでサンプルとして書いたので $a 使いすぎとかそういうところは無視。
#! /usr/bin/perl
use strict;
use utf8;

while (<>) {
  chomp;
  my $str = $_;
  utf8::decode($str);
  $str =~ /(Bulk Order Deed Blessed) (重量: \d) (小口|大口) (\w+(?: ingot(?:s)?| leather)?) (高品質|標準) (個数: \d+)/igc;
  my $a = $1;
  my $b = $2;
  my $c = $3;
  my $d = $4;
  my $e = $5;
  my $f = $6;
  utf8::encode($a);
  utf8::encode($b);
  utf8::encode($c);
  utf8::encode($d);
  utf8::encode($e);
  utf8::encode($f);
  print "\$1: [$a] \$2: [$b] \$3: [$c] \$4: [$d] \$5: [$e] \$6: [$f]";
  while ($str =~ /\G \w((?:\w|\s)+: \d+)/gc) {
    my $a = $1;
    utf8::encode($a);
    print " [$a]";
  }
  print "\n";
}

例えば布大口の巫女のデータをこのスクリプトに食わせると

$1: [Bulk Order Deed Blessed] $2: [重量: 1] $3: [大口] $4: [cloth] $5: [標準] $6: [個数: 20] [ バンダナ: 20] [ shirt: 20] [ skirt: 20] [ thigh boots: 0]

こんな風に分割して返してくれる。


UOAがクリップボードにコピーしてくれるデータって機械的に処理するのにやさしい形じゃないなぁ。
split() 一発で終わるような形でくれればいいのに。
それを簡単にパースしてくれる Perl ってすげー。

以下、俺メモ。

続きを読む

2009/04/07(火)BOD管理CGI Ver.1.0

せっかくウェブスペースを引っ越したのは Blog ツールを使うためではないのだ。

BOD管理CGI がやっと人目に晒せるようになりました。
BOD Manager

どこかに置いてあったものからの変更点は
  • [+][-]ボタンを押すごと、セル一つを編集するごとにページ遷移するのではなく、まとめて編集してから[input]ボタンを押した時にページ遷移するように変更
  • 種類を絞り込んで表示できるようにした
    • 全部一括で表示することはできなくなった
  • 内部処理を共通化、汎用化した
  • プレーンテキストに保存されていた認証パスワードを DB に格納するようにした
    • 生で保存されていたパスワードをハッシュで保存するようにした
  • ユーザー作成等の操作をウェブインタフェースからできるようにした
    • 管理者の目にしか触れないのですっごい適当
今更 BOD管理CGI もないだろう、という気はすごくしたりしなかったりするようなしないような。
JavaScript, CSS, Cookie が多分必須です。なくてもなんとかなるけど、
  • JavaScript がない場合はテキストボックスに直接入力しないとダメ。[+][-] のボタンは使えません
  • CSS がない場合は、レイアウトを大部分 CSS に頼っているのでどうなるかわかりません
  • Cookie がないとログインできないはず
入力し終わった後は、[input] ボタンを押さないと変更が反映されないので注意。

変更するかもしれなかったのに変更されなかった点
  • DB のフォーマットは SDBM のままにした
TODO:
静的データの定義は別ファイルにしよう。
UOA のベンダーエージェント情報をクリップボードからコピーしたデータによる更なる一括入力とか?だれか UOA 買ってくれ。

2009/04/02(木)俺よりエディタを信じる漢

俺はコードの階層構造はエディタの自動インデントを信じる。自分では把握しないポリシーだ。(かっこよさ気に言う事じゃありませんね)

いつまでも未完成な BOD管理CGI を久しぶりに弄った。
いじっているうちに、すっごい根本から書き直した。
一番てっぺんの呼び出し元の仕様から変えないといけない変更を入れた。
よく考えてコードを書くときはボトムアップで書くので一番下の関数を書いた。
関数を置き換えるだけにすればいいのに元あった関数もいじった。その他整形のためとかちょこちょこいじった。
なんかバグった。

コードの階層構造は自分では把握しないのでエディタがインデントを入れるに任せるんだが(えらそーに言う事じゃありませんね)、エディタのインデントが崩れている。しかし周辺に何もおかしな記述が見つからない。そもそも perl インタプリタ自体は文法上のエラーを吐かないし、premature end of script とか言わないので構造自体には問題なさそうだ。最終的に帳尻があっているだけかもしれないが、さすがに闇雲にエディタのインデントが合うように調整、みたいな書き方はしないのでこれもないだろう。
しかし、Not a CODE reference at bod_manage.pl というのは関数を定義しているうえでこんな事を言われる以上、どこかで階層構造がイカれているような気がする。自力で深く考えずに勘でいうなら、呼び出している箇所か呼び出される先のスコープがどこかおかしな所に入っている。

emacs の場合は cperl-mode を使っているが、他のインテリジェントなエディタは何か見つけるかもしれない、と思いいろいろ試す。# 自力で読む気はないらしい。

Komodo Edit を入れてみた。Komodo Edit は Perl の大御所といえるであろう、Active State がリリースしている統合開発環境からエディタだけを抜き出したもの。
意外とつかえねー。階層構造をフォールディングできる部分はすばらしい。euc-jp に対応したら使ってみようと思う。euc-kr 対応で euc-jp 非対応ってどうなのよ。

perltidy で整形してみた。
狂っていたインデントが揃った。揃っちゃったよ、ぉぃ。

emacs に戻って perl-lint-mode を使ってみる。
$_ 使うなとか配列に対する暗黙のスカラーコンテキストによる評価とか細かい警告は出るが、最終的には Syntax OK. と出る。

桜エディタを使ってみた。
自動整形機能はついてないらしい。

やべーくらい夜更かしした、早朝ミーティングの前日深夜。
直った。
気にしてた関数と全然違う所で確かに、Not a CODE reference at bod_manage.plって言われてた。
意識した関数に引数として関数を渡してるはずの箇所に関数渡ってなかった。下のほうの処理と上からの処理をすり合わせた時にミスったらしい。結局自力で気づいたか...。
ぶっちゃけ、インデントと関係ない。

これだから Perl のいないメンバオブジェクトにアクセするとオブジェクトが勝手に生えるとか関数の引数に関数を入れられる(※)とかイやなんだ!使うけど!
あと Perl の自動インデント泣かせないろんな記号をやたらと使う所。正規表現の特殊記号とか使うとどうしても崩れる。perl-mode から cperl-mode に乗り換えてかなりよくやってくれるので油断してた。
(※)正確には引数の中で関数が評価されること。C でも関数ポインタを引数として渡すとかは可能。

perl-lint-mode が呼び出しているモジュールも理解してくれるとすぐ見つかったんだろう。
つうか、Perl の Warning で行数じゃなくオブジェクト名をずばりいってくれ。細木和子張りにずばり言ってくれ。

ちなみに、CGI 自体はまだまだ、いつまでも未完成です。
バックエンドを大幅に変える、そもそも開発言語を変える、という俺しか楽しくない変更もありうる。

うちの BOD の山がこなれて来たら完成を急ぐかもしれない。