『プログラミングErlang』11.7に載っている演習の実演。サーバをVMware上のUbuntuで動かし、ホスト側のMac OS Xと合わせて計6つのクライアント・ウィンドウを開いている。グループは2つあり、「Miki」というユーザは両方のグループに(それぞれ別のクライアントとして)ログインしている。
- グループの全員の名前を表示するコードを追加してみよう
- → gsのlistboxオブジェクトを使用して実装した
- すべてのグループの一覧を表示するコードを追加してみよう
- → 同じくgsのlistboxを使用して実装した
- 1対1の会話を追加してみよう
- → メンバー一覧の中からユーザ名を選んでメッセージ送信を行うと、そのユーザに対してのみメッセージが届くようにした(スクリーンショット中「765pro」グループの「Haruka」と「Miki」のやり取り)。また自分を選ぶと自分にだけ表示されるようにした(「Yukiho」のメッセージ)
- グループコントローラをサーバマシンで動かさずに、グループに最初に入ったユーザのところで動かすためのコードを追加してみよう
- → どうしても理解できなかったので実装しなかった
以下雑感。
chat_serverとchat_groupはPidを管理するために微妙に異なるデータ構造を使っている。これが非常にイケてない。DRY原則に従って、lib_pid_assocというモジュールを作って統合した。例えば要素を取り除くremove関数は以下の通り。
remove(Pid, Assoc) -> remove(Pid, Assoc, []). remove(_, [], L) -> {"????", L}; remove(Pid, [{Key, Pid}|T], L) -> {Key, reverse(L, T)}; remove(Pid, [H|T], L) -> remove(Pid, T, [H|L]).
gsのlistboxオブジェクトは、一度何かのアイテムを選択してしまうと、マウス操作では非選択状態に戻せなくなるらしい(少なくとも私はその方法を発見できなかった)。さすがに不便なので、Membersラベルをクリックしたら選択を解除するコードを追加しておいた。
loop(W) -> receive %... {gs, label_m, buttonpress, _, _} -> gs:config(listbox_m, {selection, clear}), loop(W); %... end.
