Home日記コラム書評HintsLinks自己紹介
 

フィンローダのあっぱれご意見番 第157回「誰の子なのか知りたい」

← 前のをみる | 「フィンローダのあっぱれご意見番」一覧 | 次のをみる →

その昔、ビデオデッキというものがあった。いや、今もあるけど。 我が家では PSX を買ってからは、 ビデオテープを再生する以外にビデオデッキを使わなくなった。 いや、普通ビデオデッキはそういうものだろ、と言われそうだが、 昔は、テレビの番組を録画するのにビデオデッキを使ったのである。 録画した番組を編集してダビングしたいので、ビデオデッキは最低2台が必要だった。 βという方式のビデオデッキがあった時代の話である。

βとVHSの戦いは既に伝説である。 性能で言えば、明らかにβの方が優れていたのに、市場を圧勝したのはVHSなのだ。 βはビデオテープのサイズが小さいというだけでも非常に有利なのだが、 さらに、画質という、 ビデオを評価するにあたり重要な基準においても、 一目瞭然の差があったのである。 このクオリティの差を何とかしようと、 VHSも高画質の規格をどんどん追加していったが、 私見としては、βが高画質化していく速度には追いつかなかったと思っている。 では、クオリティで勝るβは、なぜ勝てなかったのか。 そこが伝説の伝説たる所以だ。

いいものが売れるとは限らない。 今では、メーカーの開発者には常識である。

§

これを書いている時点で、@nifty のフォーラムが全て Web 化(って何?)してから1か月以上経つ。 想像したよりは何とかなっているようだが、 ただし、私の想像はかなり厳しい状況を想定していたものなので、 何とかなっているというのは、現実的に、如何ともしがたい状況である。

  

どこがまずいのか? 一言でいって、まず使い勝手だと思う。 User Interface である。 多分、このシステムを作った人達が Webフォーラムにどっぷりハマっている…ということは有り得ないと思う。 逆に、全く使っていない、ということもないと思うけど、 昔、パソコン通信が全盛期だった頃の、一日に何時間もコメントを書いてアクセスして、 暇なときにはチャットして、 といったヘビーユーザーのスタイルでWebフォーラムを使っている人は、殆どいないような気がするのだ。

 

※ Web にすれば使わなくなる、という訳ではない。 現に、2ちゃんねるは大盛況だし、 mixi のような後発のコミュニティサービスでおいてさえ、 Web フォーラムよりも多くの人が活発に意見交換している。

つまり、そういうUIなのだ。 使い勝手が悪すぎる。

一般論として、 「いいものが売れるとは限らない」という法則は、 ソフトウェアについても完璧に当てはまるし、 もちろん、ネットのサービスについても同様である。 ソフトウェアが優れていても、 それを理由にユーザーが使ってくれるとは限らない。 つまり、UIが優れていても、使ってもらえる保証はない。 とはいえ、物事には限度というものがあるのだ。 いくら何でもこれでは…という状態では、まず売れない。 使いにくいものも売れることはあるが、 使いにくすぎると売れない。 これも法則である。

ただし、Webフォーラムに、超基本的な機能が欠けているわけではない。 超基本的というのは、投稿する、投稿されたものを読む、削除する、 その程度のものを意味する。 ということは、別に提供されたUIに固執する義務はないわけで、 その超基本的な機能に対して、UIのラッパーをかませて自分流のUIにしてしまう、 という発想が出てくる。 そこで開発しているのが「FPROG専用通信ソフト」なのだ。

そんなのまだやっているのかといわれそうだが、実はやっているのである。 今回は、それがないと「使えない」に近い状況なのだから、 かなり気合が入っている。 開発コードは Mawou と決まった。「まをう」と読む。 もしかすると、この記事が出ている頃には、Mawou で検索すれば何か情報が得られる状態になっているかもしれないが、例によって頓挫しているかもしれない。 「通信ソフト」というのはどうも前世紀的な気がするので、 最近は「FPROG専用コミュニケーションツール」と呼んだりしている。

§

  

@niftyの伝統にのっとり、今回は、 投稿された記事のことを「発言」と表現する。 @nifty のフォーラムの発言を表示するモードは、3つある。 本文表示、タイトル表示、ツリー表示だ。 この中で、ツリー表示というのは、投稿された記事の関連をツリー状態で画面に表示するというもので、 BBS 風にいえば、スレッドのタイトル表示モードである。 このモードで表示すれば、各発言の相互の関係が分かる。

 

※ ツリーが分かりやすくなるのは、 その構成要素が明確に分類でき、 かつ、子が唯一の親に関連付く場合に限る。 どのツリーに入っているか分からないような状態だと、 かえって分かりにくくなることもあるのだ。 そして、掲示板の投稿というのは、そういうことがよくあるモノの一つである。

この画面は、目で見たときには、割と簡単に分かるのだが、 今回作っているソフトウェアの目標の一つに、 投稿された記事を UML 風に表示するというのがある。 そのためには、 ツリーの状態を内部表現に変換する処理が必要だ。

発言間の関係は単純である。 規則をここで明確にしておこう。

(1) ある発言Cに対して、元になる発言Pがある場合、PをCの親発言と呼ぶ。 また、CをPの子発言、またはPのコメントと呼ぶ。

(2) 任意の発言に対して、親発言は、たかだか1つしかない。

(3) 親発言がない発言をルート発言と呼ぶ。

(4) 各発言に一意的に割り当てた正の整数値が存在する。これを発言番号、または単に番号と呼ぶ。

HTML を解析すれば、 ある発言がルート発言かどうかを判定できる。 ルート発言以外の発言に対して、 親発言が何かを知るにはどうすればよいか、 これが今回の問題である。

画面上に発言がツリーの状態で表示されているのだから、 1発言処理する毎に発言番号を覚えておく。 まずそのことを思いつくはずだ。

---- fig. 1 ツリー表示の例 ----

  1.
  | 2.
  | | 3.
  | | | 4.

---- fig. 1 end ----

fig.1 のように、 順に子発言が追加されるという流れになっている場合、 直前に処理した発言の番号を覚えていれば、それが親発言の番号のはずだ。 しかし、fig.2 のような場合もある。

---- fig. 2 ツリー表示の例 ----

  1.
  | 2.
  | | 3.
  | | | 4.
  | | 5.

---- fig. 2 end ----

5. の発言が問題だ。 5. の直前にある発言は 4. だが、5. の発言の親発言は、 2. なのだ。

目で見てツリー構造を理解するというのは、 実は、ページに表示されたインデント情報を使っているのである。 fig.2 は、インデント情報を比較しやすくするために、縦棒を入れてある。 一つずつ解釈すると、次のようになる。
1. はルート発言である。
2. は 1. の子発言である。
3. は 2. の子発言である。
4. は 3. の子発言である。
5. は?

5. は、2. の子発言である。 なぜなら、 5. は 3. と同じ位置にインデントされているからだ。 このことは、 5. が 3. と同じ親発言を持つことを意味するのである。 3. の親発言は 2. だから、 5. の親発言も 2. ということが分かるのだ。

もう少し考えてみよう。 fig.3 の場合はどうなるか。

---- fig. 3 ツリー表示の例 ----

  1.
  | 2.
  | | 3.
  | | | 4.
  | 5.
  | | 6.

---- fig. 3 end ----

4. までは fig.2 と同じだ。 5. は、今回は 2. と同じ位置にインデントされている。 従って、5. の親発言は 2. の親発言と同じ、つまり 1. である。 6. は?

fig.2 では「5. は 3. とインデントが同じ」という理由で、 「5. の親発言は 2.」 と判断した。 しかし、fig.3 の場合、6. は 3. とインデントが同じにもかかわらず、3. ではなく 5. の子発言だ。 fig. 2 との違いは、 直前の発言との関係である。 目で見れば、6. は 5. の下にぶら下がっているのである。

結局、 インデントが直前の発言よりも深い方向に進んでいる場合は、 その発言は直前の発言の子発言だと解釈すればよさそうだ。 まとめると、こうなる。

・インデントが直前の発言よりも深ければ、親発言は直前の発言である。

・インデントが直前の発言よりも深くなければ、親発言は、この発言をさかのぼって最初に見つかったインデントが同じレベルの発言の親発言と同じである。

文章にするといまいちだが、 要するに、画面上で見て同じインデント位置、ということを言いたいだけだ。

なお、このルールは、ツリーの途中の発言が削除されるとややこしいことになるのだが、幸い、@niftyのフォーラムの場合、発言が削除されたときは、その発言があった位置に発言番号が表示され、発言が削除されたという趣旨の説明文が入る。

§

このルールでプログラムを書くときに問題になりそうなのは、 「発言をさかのぼって最初に見つかったインデントが同じレベルの発言」をどうやって見つけるのか、ということだろう。 実はこれは簡単である。 単に配列を用意するだけで処理できるのだ。

この配列には、 インデントレベルがnのときの発言を参照するためのポインタ等を入れておく。 fig.3 で考えてみると、 table[0] には 1. (を指すポインタ)が入る。 2. のインデントレベルは1なので、 table[1] には 2. が入る。 同様に、 table[2] には 3. が入る。 table[3] には 4. が入る。 問題は 5. だ。 4. のインデントレベルは3、 5. のインデントレベルは1、 すなわち、減少している。 ここで、5. の親を知るために「発言をさかのぼって」という処理が必要になる。 5. のインデントレベルは1だから、 table[1] を見ると、2. が入っている。 つまり、5. は 2. と同じ親発言を持つことが分かる。 2. の親発言は 1. だから、5. の親発言も 1. であることが分かる。

ここで、table[1] に、5. を入れる。 ここが重要なのだが、table に上書きすることで「さかのぼって最初に見つかった」という条件を表現するのだ。 このことに気付けば、プログラミングは簡単なのだが、そうでないと、かなりややこしいことになりそうな気がする。

なお、この時点で、table[2] と table[3] に入れた内容は無効になっているはずなのだが、 次に発言が出てきたときには、 インデントレベルが 1 以下か、1つ増えて 2 になるか、いずれかである。 そして、2 に増えた場合には、新たに table[2] に書き込むことになるから、 無効になった情報はそのまま捨て置いてもかまわないことがわかる。

  

(C MAGAZINE 2005年7月号掲載)
内容は雑誌に掲載されたものと異なることがあります。

修正情報:
2006-03-01 裏ページに転載。

(C) Phinloda 2005, 2006 All rights reserved.