module programming

### モジュール

plumのモジュールはすべてperlで書かれています。 普通のperlスクリプトとは違って、plumからモジュールとして 使えるようにするためのいくつかの手続きが必要ですが、 基本的にはperlさえ知っていれば、plumのモジュールを作るのも簡単です。
plumのモジュールはイベントに対する処理を行うサブルーチンの集まりです。 モジュールには、どんなイベントが発生したときにどんな処理を行うかを サブルーチンに書いておくだけで、あとはplumがイベントの発生に応じて、 それらのサブルーチンを実行してくれます。

### サブルーチン

plumは何かのイベントが発生すると、 各モジュールにある特定の名前のサブルーチンを実行します。 このサブルーチンの名前はイベントごとに1つ1つ決まっており、 イベントが発生すると、それに対応する名前のサブルーチンが実行されます。 このサブルーチン名は以下のようになっています。

main_loop (ユーザNO)
  メインループを処理するごとに実行されます。
module_enable (ユーザNO)
  モジュールの使用を開始したときに実行されます。
module_disable (ユーザNO)
  モジュールの使用をやめたときに実行されます。
server_open (ファイルNO)
  サーバに接続したときに実行されます。
server_close (ファイルNO)
  サーバとの接続が閉じられたときに実行されます。
client_open (ファイルNO)
  クライアントを接続したときに実行されます。
client_close (ファイルNO)
  クライアントとの接続が閉じられたときに実行されます。
server_read (ファイルNO, メッセージ)
  サーバから入力があったときに実行されます。
server_write (ファイルNO, メッセージ)
  サーバに出力するときに実行されます。
client_read (ファイルNO, メッセージ)
  クライアントから入力があったときに実行されます。
client_write (ファイルNO, メッセージ)
  クライアントへ出力するときに実行されます。
ss_コマンド (ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  サーバからコマンドの入力があったときに実行されます。
sp_コマンド (ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  サーバへコマンドを出力するときに実行されます。
cs_コマンド (ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  クライアントからコマンドの入力があったときに実行されます。
cp_コマンド (ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  クライアントへコマンドを出力するときに実行されます。
cpss_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  サーバからPRIVMSGでCTCPのコマンドの入力があったときに実行されます。
cpsp_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  サーバへPRIVMSGでCTCPのコマンドを出力するときに実行されます。
cpcs_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  クライアントからPRIVMSGでCTCPのコマンドの 入力があったときに実行されます。
cpcp_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  クライアントへPRIVMSGでCTCPのコマンドを出力するときに実行されます。
cnss_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  サーバからNOTICEでCTCPのコマンドの入力があったときに実行されます。
cnsp_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  サーバへNOTICEでCTCPのコマンドを出力するときに実行されます。
cncs_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  クライアントからNOTICEでCTCPのコマンドの 入力があったときに実行されます。
cncp_コマンド (ファイルNO, プレフィクス, コマンド, チャンネル, 引数)
  クライアントへNOTICEでCTCPのコマンドを出力するときに実行されます。

それぞれのサブルーチンは受け取った引数を戻り値として返す必要があります。 このとき返すものは受け取った引数から先頭の要素を取り除いたものです。 引数が1つのサブルーチンは何も返す必要はありません。 引数はモジュールの中で変更してもかまいません。 また、このときコマンドを空文字列として返すと、 そのメッセージはそこで消滅します。

### パッケージ

plumのモジュールはそれぞれが1つ1つのパッケージを持っています。 それぞれが独立したパッケージを持つことによって、 変数名などが他のパッケージと重なっても大丈夫なようになっています。 パッケージ名は原則としてディレクトリ名とファイル名を 「_」でつないだものです。 例えば、「dir/module.plm」のパッケージ名は「dir_module」になります。 モジュールのディレクトリやファイル名には「_」は使わないようにして下さい。
各モジュールは初期化したときに、 必ずそれぞれのモジュールのパッケージ名を返さなければいけません。 パッケージの名前は「$_」に入れて返します。 また、モジュールを見やすくするため、グローバルな変数の初期化は 「$_」への代入の前に行うようにして下さい。