variable and subroutine

### 変数とサブルーチン

モジュールからplumの情報を知るために、いくつかの変数を参照することができます。 また、モジュールの開発を容易にするために、 いくつかのサブルーチンが用意されています。 これらの変数やサブルーチンは全てmainパッケージにあります。 mainパッケージ以外にある変数やサブルーチンは使用してはいけません。

### モジュールから参照できる変数

モジュールから参照できる変数には以下のようなものがあります。 変数名の最後にlistが付いているものは、スカラにパックされたリストです。 これらはそれぞれの要素を、間にセパレータをはさんでつなげたものです。 またリストの先頭にもセパレータが付加されています。 ただし空のリストは空文字列と同じです。 リストには重複した値を格納することはできません。
plumの内部では主にユーザNOとファイルNOでデータを管理しています。 ユーザNOはplumが読み込んだ設定ファイルに対応しており、 設定ファイルを3つ読み込むと、0,1,2の3つのユーザNOがそれぞれ割り当てられます。 これらはそれぞれ別々のIRCネットワークに接続されている可能性があるため、 それぞれのユーザNOで変数の値も別々に管理しています。 また、ファイルNOはplumが開いたソケットのファイルハンドルと対応しています。 これはfileno(ファイルハンドル)で得られる値です。

#### スカラ変数

$'rin
  入力ファイルハンドルのマスクです。 ファイル番号に対応するビットを1にします。
$'win
  出力ファイルハンドルのマスクです。 ファイル番号に対応するビットを1にします。
$'rout
  入力の準備ができているファイルハンドルのマスク ファイル番号に対応するビットが1になります。
$'wout
  出力の準備ができているファイルハンドルのマスク ファイル番号に対応するビットが1になります。
$'serverlist
  全てのサーバのファイルNOのリストです。
$'clientlist
  全てのクライアントのファイルNOのリストです。
$'listenlist
  全ての接続待ちのソケットのファイルNOのリストです。
$'kanjilist
  漢字での正規表現をサポートしている漢字コードのリストです。

#### 配列変数

$'username[ユーザNO]
  それぞれのユーザのユーザ名です。ユーザ名はplumの実行時に 指定した引数で、IRC上でのユーザ名とは一切関係ありません。
$'filename[ユーザNO]
  それぞれのユーザの設定ファイルのファイル名です。
$'modulelist[ユーザNO]
  それぞれのユーザが組み込んでいるモジュールのリストです。 リストの要素はモジュールのパッケージ名です。
$'server[ファイルNO]
  それぞれのファイルNOに対応するサーバのファイルNOです。 サーバに接続していない時の値は不定です。
$'channellist[ファイルNO]
  それぞれのファイルNOで現在入っているチャンネルのリストです。
$'userno[ファイルNO]
  それぞれのファイルNOが属するユーザNOです。 基本的にそれぞれのファイルNOはどれかのユーザNOに属していますが、 初期前のクライアントのファイルNOはどのユーザNOにも属しません。
$'servername[ファイルNO]
  それぞれのファイルNOに対応するサーバの名前です。 サーバ名はサーバが送ってくる名前で、 必ずしもマシン名と一致するとは限りません。
$'socket[ファイルNO]
  ファイルNOに対応するファイルハンドル名です。
$'avail[ファイルNO]
  それぞれのファイルNOについて、初期化が終わっているかどうかの 論理値です。初期化が終わっていれば真(1)、そうでなければ偽(0)です。 ファイルNOがクライアントのものならば、クライアントから正しい パスワードとニックネームとユーザ名を受け取ると1になります。 また、ファイルNOがサーバのものならば、サーバに正しいパスワードと ニックネームとユーザ名を送ると1になります。
$'nick[ファイルNO]
  それぞれのファイルNOでのニックネームです。
$'user[ファイルNO]
  それぞれのファイルNOでのユーザ名です。 このユーザ名は$'username[ユーザNO]の値とは全く関係なく、 IRC上でのユーザ名です。
$'access[ファイルNO]
  それぞれのファイルNOの最後に入力のあった時間です。 この時間はtime()で返される値と同じもので、 クライアントやサーバだけでなく、すべてのソケット ファイルハンドルに対して正しい値を持っています。

#### ハッシュ変数

$'filename{パッケージ名}
  パッケージ名に対応するモジュールのファイル名です。
$'dirctory{パッケージ名}
  パッケージ名に対応するモジュールが存在するディレクトリです。
$'package{ファイル名}
  モジュールのファイル名に対応するパッケージ名です。
$'labellist{ユーザNO, パッケージ名}
  それぞれのパッケージに対応するラベルのリストです。
$'nameslist{ファイルNO, チャンネル名}
  それぞれのチャンネルに入っているニックネームのリストです。 ニックネームにはオペレータやモデレータの記号を含みます。 チャンネルに、「pupu」、「plum」という2人の人が入っており、 pupuがチャンネルオペレータの場合、これは 「@pupu」と「plum」という要素を含むリストになります。
$'channelmode{ファイルNO, チャンネル名, モード}
  それぞれのチャンネルに設定されているチャンネルモードです。 値を持つモードならその値が、それ以外のモードについては 設定されていれば1になります。
$'topic{ファイルNO, チャンネル名}
  それぞれのチャンネルに設定されているトピックの値です。

### モジュールから利用できるサブルーチン

モジュールから利用できるサブルーチンには以下のようなものがあります。

#### システム状態取得

&'property(ユーザNO, プロパティ名) : プロパティ値
  設定ファイルで設定されているプロパティの値を参照します。 プロパティ名にはパッケージ名を含みません。 つまり、dir/module.plmで「key」というプロパティ名を指定すると、 設定ファイル中の「dir.module.key」の値が得られます。 またサブルーチンをスカラコンテキストで評価すると、 最初に設定したプロパティの値を得られます。 配列コンテキストで評価すると、全ての設定が得られます。
&'load(ユーザ名, ファイル名)
  ユーザ名に対応する設定ファイルを読み込みます。 このサブルーチンはなるべく使用しないで下さい。
&'import(ユーザNO,ファイル名)
  指定したモジュールを読み込みます。 モジュールの初期化は行われますが、組み込みは行われません。 このサブルーチンはなるべく使用しないで下さい。

#### 文字列変換

&'prefix(プレフィクス) : (ニックネーム, ユーザ名, ホスト名)
  プレフィクスを分解してニックネーム、ユーザ名、 ホスト名の配列を得ます。
&'regex(ワイルドカード) : 正規表現
  ワイルドカードの文字列を正規表現の文字列に変換します。
&'expand(ファイル名) : ファイル名
  ~で始まるパスを実際のパスに変換します。 「~/」は環境変数HOMEの値に置き換えます。 「~user」はuserのホームディレクトリの値に置き換えます。
&'timelocal(秒, 分, 時, 日, 月, 年) : 秒
  localtimeと逆の動作をします。
&'date(フォーマット, 時間) : 文字列
  フォーマットに従って日付や時間を展開します。 引数として時間を指定すると、その時間として展開し、 指定しなかった場合は現在の時間として展開します。
&'format(フォーマット, ハッシュ)
  フォーマットに従ってハッシュのデータを展開します。
&'real(チャンネル名) : チャンネル名
  エイリアスのチャンネル名から実際のチャンネル名を得ます。 エイリアスは%で始まるチャンネル名です。
&'alias(チャンネル名) : チャンネル名
  実際のチャンネル名からエイリアスのチャンネル名を得ます。
&'channel(文字列) : 論理値
  文字列がチャンネル名ならが真を、そうでなければ偽を返します。
&'parse(メッセージ) : (プレフィクス, コマンド, 引数1, 引数2, ...)
  IRCのメッセージを解析して、plumの内部で使用する配列に変換します。 このサブルーチンはなるべく使用しないで下さい。
&'build(プレフィクス, コマンド, 引数1, 引数2, ...) : メッセージ
  plumの内部で使用している配列をサーバやクライアントに 送ることができるメッセージに変換します。 このサブルーチンはなるべく使用しないで下さい。

#### リスト操作

&'list(要素1, 要素2, ...) : リスト
  配列からリストを生成します。
&'add(リスト, 要素1, 要素2, ...) : リスト
  リストに指定した要素を追加します。
&'remove(リスト, 要素1, 要素2, ...) : リスト
  リストから指定した要素を取り除きます。
&'change(リスト, 要素1, 要素2, 要素3, 要素4, ...) : リスト
  リストの要素を変更します。 要素1は要素2に変更され、要素3は要素4に変更されます。 要素の数が奇数のときは、最後の要素については無視されます。
&'exist(リスト, 要素1, 要素2, ...) : 論理値
  リストに指定された要素が含まれているかどうかを返します。 複数の要素を指定したときは、 そのうちのどれか1つでも含まれていれば真になります。
&'array(リスト) : 配列
  リストから配列を生成します。

#### 漢字コード変換

&'euc_euc(EUC文字列) : EUC文字列
  EUCコードの文字列をEUCコードの文字列に変換します。
&'euc_jis(EUC文字列) : JIS文字列
  EUCコードの文字列をJISコードの文字列に変換します。
&'euc_sjis(EUC文字列) : SJIS文字列
  EUCコードの文字列をSJISコードの文字列に変換します。
&'jis_euc(JIS文字列) : EUC文字列
  JISコードの文字列をEUCコードの文字列に変換します。
&'jis_jis(JIS文字列) : JIS文字列
  JISコードの文字列をISO-2022-JPで規定されている JISコードの文字列に変換します。
&'jis_sjis(JIS文字列) : SJIS文字列
  JISコードの文字列をEUCコードの文字列に変換します。
&'sjis_euc(SJIS文字列) : EUC文字列
  SJISコードの文字列をEUCコードの文字列に変換します。
&'sjis_jis(SJIS文字列) : JIS文字列
  SJISコードの文字列をJISコードの文字列に変換します。
&'sjis_sjis(SJIS文字列) : SJIS文字列
  SJISコードの文字列をSJISコードの文字列に変換します。

#### サーバ入出力

&'s_print(ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  サーバにメッセージを送ります。 プレフィクスは必要がなければ指定しないで下さい。
&'s_flush(ファイルNO)
  サーバの出力バッファにたまっているメッセージを全てサーバに送ります。
&'s_connect(ユーザNO)
  サーバへ接続します。
&'s_close(ファイルNO)
  指定したサーバへの接続を閉じます。

#### クライアント入出力

&'c_print(ファイルNO, プレフィクス, コマンド, 引数1, 引数2, ...)
  クライアントにメッセーへ送ります。
&'c_flush(ファイルNO)
  クライアントの出力バッファにたまっているメッセージを 全てクライアントに送ります。
&'c_close(ファイルNO)
  指定したクライアントとの接続を閉じます。

#### ネットワーク操作

&'connect(サーバ名, ポート番号) : ファイルNO
  指定したサーバの指定したポートへ接続します。
&'listen(ポート番号) : ファイルNO
  指定したポートでクライアントからの接続を受けつけます。
&'accept(ファイルNO) : ファイルNO
  指定したファイルNOのポートに接続してきたクライアントを接続します。
&'close(ファイルNO)
  指定したファイルNOとの接続を閉じます。
&'sockname(ファイルNO) : (ポート番号, IPアドレス, ホスト名)
  指定したファイルNOのソケットのこちら側の情報を得ます。 ポート番号、IPアドレスは符号なしの整数です。 IPアドレスからホスト名が得られない場合、ホスト名は空になります。
&'peername(ファイルNO) : (ポート番号, IPアドレス, ホスト名)
  指定したファイルNOのソケットの相手側の情報を得ます。 ポート番号、IPアドレスは符号なしの整数です。 IPアドレスからホスト名が得られない場合、ホスト名は空になります。
&'user(ファイルNO) : プレフィクス
  指定したファイルNOでのプレフィクスを得ます。