T.MURACHIの日記: 擬似ハッシュ。。。
TODO リスト CGI 作成中。。。
作業分類は設置者が設定できるようにしようということで、作業分類の定義ファイルを別途設けて、そこから読み出すようにすることにしました。こいつは作業分類を表す ID 名 (プログラム内部で使う名前) と表示名をタブ文字区切りで対応付けたもの。TODO リストを表示するときに読み込んで、TODO リストの各行ごとに、作業分類の部分で実際に表示する名前に置き換えるということをやりたいので、そう考えれば単純に ID 名をキーにした連想配列にしてあげれば良いように見えますよね。
ところが、TODO を新規に登録するときには、作業分類をコンボボックスから選択するようにするのですが、このときコンボボックス内での並び順は、定義ファイルで書いたのと同じ順番で並んだ方が、設置者にはありがたいよなぁとか思ってしまいました。実は最初はこっちのことしか考えていなくて、作業分類を読み出すサブルーチンでは ID と表示名をそれぞれ 'id' と 'name' でキーにしたハッシュ配列として作るように書いてしまい、後でリスト表示画面の HTML を出力する部分を書きながら、あ、これじゃあ ID で引っ掛けられないじゃん、ということに気付いたというお間抜けっぷりだったわけです。
で、そこで登場したのが擬似ハッシュ。もう、ラクダ本の説明を見るからにややこしくって絶対に手を出すものかと誓っていたのに、早くも利用する羽目になってしまった。。。
どうやったのかというと、イメージ的には以下のようになるように擬似ハッシュを作成し、
$components = [
{'design' => 1, 'program' => 2, 'cg' => 3, 'sound' => 4},
{'id' => 'design', 'name' => '仕様 / 設計'},
{'id' => 'program', 'name' => 'プログラム'},
{'id' => 'cg', 'name' => 'CG'},
{'id' => 'sound', 'name' => 'サウンド / BGM'}
];
TODO リスト表示で作業分類 ID を表示名に変換する際には以下のように使用し (HTML タグ表記は開きアングルがどうにも半角で入力できないので、アングルだけ全角で記述させていただきやす)、
print qq| <TD>$components->{'program'}{'name'}</TD>\n|;
そして登録時のコンボボックスは以下の要領で使用する、という感じです。
print qq|<SELECT NAME="component">\n|;
foreach (@$components[1..scalar(@$components)-1]){ # 2/10 訂正。。。ごめんなさい実はここ何度も訂正してます (;_;)/
my $selected = $_->{'id'} eq $default_components ? ' SELECTED' : '';
print qq| <OPTION VALUE="$_->{'id'}"$selected>$_->{'name'}</OPTION>\n|
}
print qq|</SELECT>\n|;
ちなみに、前者の、表示名に変換する方は、実際には TODO リストの各行のデータは、項目をキーとしたハッシュへの参照を配列にした、いわゆるハッシュ配列というやつだったりするので、こーんな感じの記述になっちゃっていたりしています。
foreach (@todo){
print qq|<TR>\n|;
# ...
print qq| <TD>$components->{$_->{'component'}}{'name'}</TD>\n|;
# ...
print qq|</TR>\n|;
}
フフフ。。。Perl がこれほどまでにお酒が恋しくなる言語だったとは思わなかったよ。
-
# 2004/02/15 追記:
何度か書き直ししている以下の部分ですが、
foreach (@$components[1..scalar(@$components)-1]){
scalar 関数を使わずとも、以下の書き方でいけるみたいです。
foreach (@$components[1..$#$components]){
配列の要素であることを表す 1 つ目のダラーのすぐ後ろにハッシュを入れるのがミソだったみたいです。これが分からなくて、一生懸命 $$#components だの、@$#components だの、いや実は $#components で良いんではないか? だのとやっていて、結局諦めて scalar 使っちゃってたんですが。。。むぅ。
擬似ハッシュ。。。 More ログイン