PERLGUTS(1) USER COMMANDS PERLGUTS(1)
NAME
perlguts - Perl の内部関数
DESCRIPTION
このドキュメントでは Perl の実行ファイルの内部関数をいくつか
記述しています。 完璧なものではありませんし、間違いも多いと
思います。 疑問点やコメントは後に示す著者に行なってください。
データ型
Perl では、主となる 3 つのデータ型を扱うために 3 つの typedef
を行なっています:
SV スカラ値
AV 配列値
HV ハッシュ値
それぞれの typedef には様々なデータ型を操作するための特別な
ルーティンが用意されています。
"IV" とは
Perl では、整数でもポインタでも十分に入れることのできる、特
別な typedef IV を使います。
Perl ではまた、常に 32 bit の整数となる特別な typedef I32 も
使用します。
SV の操作
SV は、1 つのコマンドで生成し、値をロードすることができます。
ロードできる値の型には、整数 (IV)、倍精度 (NV)、文字列 (PV)、
その他のスカラ (SV) があります。
これらを行なう、4 つのルーティンは:
SV* newSViv(IV);
SV* newSVnv(double);
SV* newSVpv(char*, int);
SV* newSVsv(SV*);
です。 「既に存在する」スカラの値を変更するために 5 つのル
ーティンがあります:
void sv_setiv(SV*, IV);
void sv_setnv(SV*, double);
void sv_setpvn(SV*, char*, int)
void sv_setpv(SV*, char*);
void sv_setsv(SV*, SV*);
Perl manpages Last change: Release 5.0 Patchlevel 00 1
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
sv_setpvn を使って、代入される文字列の長さを指定することもで
きますし、sv_setpv を使って Perl に長さを算出させることもで
きます。 ただし、sv_setpv は、文字列の長さを NUL 文字で終了
することに依存する strlen を使って算出することに注意しなくて
はなりません。
SV が指し示す実際の値をアクセスするには、実際のスカラの型を
強制的に IV や倍精度や文字列にする、
SvIV(SV*)
SvNV(SV*)
SvPV(SV*, STRLEN len)
というマクロを使うことができます。
SvPV マクロでは、返される文字列の長さは、変数 len に納められ
ます (これはマクロですので、&len としないでください)。 もし、
データの長さを気にしないのであれば、グローバル変数 na を使っ
てください。 ただし、Perl では NUL を含む文字列も、NUL で終
端しない文字列も許されるということを忘れないでください。
単にスカラ値が真かどうかを知りたいだけならば、
SvTRUE(SV*)
を使うことができます。
Perl では、SV にもっとメモリを割り当てて欲しいときには、自動
的に文字列を大きくしてくれますが、まだメモリを割り当てないと
いけないかを判断してくれる、
SvGROW(SV*, STRLEN newlen)
というマクロが使えます。 もし必要なら、このマクロが sv_grow
を呼びます。 SvGROW は SV に割り当てたメモリを増やすだけで、
減らすことはできません。
手元にある SV の Perl から見た、データの種類を知りたいときに
は、その SV の型チェックに、
SvIOK(SV*)
SvNOK(SV*)
SvPOK(SV*)
というマクロを使うことができます。
SV に納められた文字列の、現在長を取得したり設定したりするに
は、以下のマクロが使います。
SvCUR(SV*)
SvCUR_set(SV*, I32 val)
Perl manpages Last change: Release 5.0 Patchlevel 00 2
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
ただし、これらは SvPOK() が真のときだけ有効です。
もし、スカラ変数の名前がわかるならば、その SV へのポインタは、
SV* perl_get_sv("varname", FALSE);
を使って得られます。 その変数が存在しなければ、NULL が返さ
れます。
その変数 (あるいは、他の任意の SV) が、実際に定義されている
かを知りたいならば、
SvOK(SV*)
を呼び出してください。
スカラの undef 値は、sv_undef という SV インスタンスに納めら
れています。 そのアドレスは、SV* が必要とされるところで使用
することができます。
ブール値の真と偽を表わす、sv_yes と sv_no という値もあります。
sv_undef と同様に、これらのアドレスも SV* が必要なところで、
使うことができます。
(SV *0) が &sv_undef が同じであると考えて、だまされてはいけ
ません。 次のようなコードを見てください:
SV* sv = (SV*) 0;
if (I-am-to-return-a-real-value) {
sv = sv_2mortal(newSViv(42));
}
sv_setsv(ST(0), sv);
このコードは、実値を返さなければならないときには、(値として
42 を持つ) 新しい SV を返そうとし、さもなくば undef を返そう
とします。 ですが、どこかの行でヌルポインタを返して、セグメ
ントバイオレーションが起こるか、何かおかしな結果になってしま
います。 最初の行の 0 を &sv_undef に変えれば、すべてが旨く
いきます。
生成した SV を解放するためには、SvREFCNT_dec(SV*) を呼びます。
普通は、この呼び出しは必要ありません。 「揮発性」の章を参照
してください。
プライベート値とバブリック値
自分で持っていれるスカラの型を決定する通常の方法は、マクロ
Sv[INP]OK を使うのでした。 スカラは数値にも文字列にもなり得
ますから、普通、これらのマクロはいつも真を返し、Sv[INV]V マ
クロを呼ぶことで、文字列から整数/倍精度、整数/倍精度から文字
列への変換を行ないます。
Perl manpages Last change: Release 5.0 Patchlevel 00 3
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
もし、本当に SV にあるのが整数か、倍精度か、文字列ポインタか
を知りたいのであれば、代わりに、
SvIOKp(SV*)
SvNOKp(SV*)
SvPOKp(SV*)
というマクロを使うことができます。 これらは、実際に SV に入
っているものが整数か、倍精度か、文字列ポインタかを教えてくれ
ます。
しかし、一般には、Sv[INP]V マクロを使うだけにした方が良いで
しょう。
AV を使う
AV を生成して、値を設定するのには、2 つの方法があります。
最初の方法は、単に空の AV を作るものです:
AV* newAV();
ふたつめの方法は、AV を生成した上で、初期値として SV の値を
入れます:
AV* av_make(I32 num, SV **ptr);
ふたつめの引数は、num 個の SV* の配列を指しています。
いったん、AV が生成されると、AV に対して、
void av_push(AV*, SV*);
SV* av_pop(AV*);
SV* av_shift(AV*);
void av_unshift(AV*, I32 num);
といった操作が行えます。 これらは、av_unshift を除いては、
お馴染みの演算でしょう。 av_unshift は、配列の先頭に、num
個の undef 値の要素を付け加えます。 その後で、(あとで述べる)
av_store を使って、新しい要素に値を代入しなければなりません。
他にもいくつか関数があります:
I32 av_len(AV*); /* 配列の大きさを返す */
SV** av_fetch(AV*, I32 key, I32 lval);
/* オフセットが key の位置から値を取り出すが、lval
がゼロでないとき、値を lval に設定するようだ */
SV** av_store(AV*, I32 key, SV* val);
/* オフセットが key の位置に val を設定する */
Perl manpages Last change: Release 5.0 Patchlevel 00 4
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
void av_clear(AV*);
/* すべての要素をクリアするが、配列は残す */
void av_undef(AV*);
/* 全要素を除去し、配列を未定義にする */
配列変数の名前がわかるのであれば、
AV* perl_get_av("varname", FALSE);
を使えば、AV へのポインタが得られます。 その変数が存在しな
ければ、NULL を返します。
HV を使う
HV を生成するには、
HV* newHV();
というルーティンを使います。 いったん、HV が生成されると、
HV に対して、
SV** hv_store(HV*, char* key, U32 klen, SV* val, U32 hash);
SV** hv_fetch(HV*, char* key, U32 klen, I32 lval);
という操作が行えます。 引数 klen は、渡される key の長さで
す。 引数 val は、設定されるスカラへの SV ポインタを入れ、
hash は、あらかじめ計算したハッシュ値 (hv_store に計算させる
場合には、ゼロ) です。 引数 lval で、このフェッチ操作が、実
はストア操作の一部であるかを示します。
hv_store や hv_fetch は、SV** を返すもので、SV* ではないこと
に注意してください。 スカラ値をアクセスするには、まず返却値
を被参照する必要があります。 しかし、その前に返却値が NULL
でないことを確認すべきです。
ハッシュテーブルのエントリが存在するかをチェックし、削除する
関数があります。
bool hv_exists(HV*, char* key, U32 klen);
SV* hv_delete(HV*, char* key, U32 klen);
そして、その他の諸々の関数:
void hv_clear(HV*);
/* ハッシュテーブルのすべてのエントリをクリアする */
void hv_undef(HV*);
/* ハッシュテーブルを未定義にする */
I32 hv_iterinit(HV*);
/* ハッシュテーブルを走査する開始点を準備する */
Perl manpages Last change: Release 5.0 Patchlevel 00 5
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
HE* hv_iternext(HV*);
/* 次のエントリを取り出し、key と value が入った
構造体へのポインタを返す */
char* hv_iterkey(HE* entry, I32* retlen);
/* HE 構造体から key を取り出し、また、key 文字
列の長さを返す */
SV* hv_iterval(HV*, HE* entry);
/* HE 構造体の value への SV ポインタを返す */
ハッシュ変数の名前がわかるのであれば、
HV* perl_get_hv("varname", FALSE);
を使うことで、HV へのポインタが得られます。 その変数が存在
しなければ、NULL を返します。
(興味ある方のために、) ハッシュのアルゴリズムは、
i = klen;
hash = 0;
s = key;
while (i--)
hash = hash * 33 + *s++;
となっています。
リファレンス
リファレンスは、(リファレンスを含む) 他のスカラ型を指す、特
別なスカラ型です。 AV や HV をスカラとして扱うには、単に AV
や HV を SV にキャストするだけのことです。
リファレンスを生成するには、
SV* newRV((SV*) pointer);
というコマンドを使います。 いったん、リファレンスができると、
適切な typedef (AV, AV, HV) へのキャストを用いて、
SvRV(SV*)
というマクロが使うことができ、返された SV* を AV* か HV* に
キャストして、適切なルーティンを呼ぶことになります。
リファレンスを被参照した後も、まだリファレンスであるかを調べ
るには、
SvROK(SV*)
というマクロが使えます。
Perl manpages Last change: Release 5.0 Patchlevel 00 6
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
XSUB と引数スタック
XSUB の仕組みは、Perl プログラムが C のサブルーティンをアク
セスするための単純な方法です。 XSUB には、Perl プログラムか
らの引数を入れるスタックと、Perl のデータ構造を C の同等なも
のにマッピングする方法を用意しています。
スタック引数は、ST(n) というマクロでアクセスできます。 これ
は、n 番目のスタック引数を返すものです。 引数 0 は、Perl の
サブルーティン呼び出しで渡された、最初の引数です。 これらの
引数は SV* で、SV* が使われるところであれば、どこでも使うこ
とができます。
ほとんどの場合には、C ルーティンからの出力は、RETVAL と
OUTPUT: ディレクティブを使って扱うことができます。 しかし、
引数スタックのスペースがすべての返却値を扱うのに、十分でなく
なる場合があります。 例としては、引数をとらないで、ローカル
なタイムゾーンと、夏時間の省略形の二つの返却値を返す、POSIX
tzname() の呼び出しがあります。
このような状況を扱うためには、PPCODE: ディレクティブを使い、
EXTEND(sp, num);
というマクロを使ってスタックを拡張します。 ここで、sp はス
タックポインタで、num はスタックを拡張すべき要素の数です。
スタック上に場所を確保したならば、IV、倍精度、文字列、SV ポ
インタをプッシュする、
PUSHi(IV)
PUSHn(double)
PUSHp(char*, I32)
PUSHs(SV*)
というマクロを使って、値をスタックへプッシュします。
これで、tzname をよぶ Perl プログラムでは、二つの値は、
($standard_abbrev, $summer_abbrev) = POSIX::tzname;
というように代入できます。 スタックに値を積む、別の (おそら
く、より簡単な) 方法は、
XPUSHi(IV)
XPUSHn(double)
XPUSHp(char*, I32)
XPUSHs(SV*)
というマクロを使うものです。 こちらのマクロは、必要ならば、
自動的にスタックを調整してくれます。
Perl manpages Last change: Release 5.0 Patchlevel 00 7
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
揮発性
Perl では、値は通常「不揮発な」ものです。 つまり、(Perl の
undef 呼び出しや、Perl 自身で他のルーティンを通じて) 明示的
に解放しない限り、解放されることはありません。
先の tzname の例では、文字列であるところの、二つの新しい SV
を引数スタックに積むために、生成する必要がありました。 しか
し、これらは最終的にはスカラ変数を保持する SV にコピーされま
すから、新しい SV に永久に固執するものではありません。
「揮発性」の SV (あるいは、AV や HV) は、普通の「不揮発性」
の SV、AV、HV と全く同じように動作しますが、「現在の文脈」で
しか有効ではないものです。 Perl インタプリタが現在の文脈を
離れると、揮発性の SV、AV、HV は自動的に解放されます。 一般
に「現在の文脈」というのは、Perl の一つの実行文を表わします。
揮発性の変数を生成するには、
SV* sv_newmortal()
SV* sv_2mortal(SV*)
SV* sv_mortalcopy(SV*)
という関数を使います。 最初のものは揮発性の SV を生成し、ふ
たつめは、既にある SV を揮発性の SV に変換します。 三つめは、
既に存在する SV の揮発性のコピーを生成します。
揮発性のルーティンは、単に SV のためだけではありません。 AV
や HV も、sv_2mortal や sv_mortalcopy ルーティンに、アドレス
を (SV* にキャストして) 渡すことで、揮発性にすることができま
す。
新しい変数の生成
Perl スクリプトからアクセスできる、新しい Perl の変数を生成
するには、変数の型に応じて、
SV* perl_get_sv("varname", TRUE);
AV* perl_get_av("varname", TRUE);
HV* perl_get_hv("varname", TRUE);
というルーティンを使用します。 二番目の引数としては TRUE を
使います。 新しい変数は、データの型に合ったルーティンを使っ
て、設定することができます。
スタッシュとオブジェクト
スタッシュとは、パッケージ内にある、すべての異なるオブジェク
トが入っているハッシュテーブル (連想配列) のことです。 ハッ
シュテーブルの個々の key は、(同じ名前のすべての異なる型のオ
ブジェクトで共有される) シンボル名で、ハッシュテーブルの個々
の value は、(グローバル値のための) GV と呼ばれます。 GV に
は、
Perl manpages Last change: Release 5.0 Patchlevel 00 8
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
スカラ値
配列値
ハッシュ値
ファイルハンドル
ディレクトリハンドル
フォーマット
サブルーティン
を含む (これらに限りませんが)、その名前の様々なオブジェクト
へのリファレンスが次々に入ることになります。
Perl は、(グローバル変数のための) GV 構造体に様々なスタッシ
ュを入れますが、それらは、HV 構造体で表されます。
特定のパッケージの HV ポインタの入手には、
HV* gv_stashpv(char* name, I32 create)
HV* gv_stashsv(SV*, I32 create)
という関数を使います。 最初の関数が、リテラル文字列をとり、
二番目が SV に入れた文字列を使います。
gv_stash*v が使う name は、シンボルテーブルを手に入れようと
するパッケージの名前です。 デフォルトのパッケージは、main
というものです。 多重にネストしたパッケージであれば、Perl
での場合と同様に、:: で区切って gv_stash*v に名前を渡すのが
正しい方法です。
もし、bless されたリファレンスである SV があれば、
HV* SvSTASH(SvRV(SV*));
を使っても、スタッシュポインタを探すことができ、パッケージ名
自身は、
char* HvNAME(HV* stash);
で得られます。
Perl スクリプトへ bless された値を返す必要があれば、
SV* sv_bless(SV*, HV* stash)
という関数が使えます。 最初の引数 SV* は、リファレンス、二
番目の引数がスタッシュです。 返された SV* は、他の SV と同
様に使うことができます。
マジック
[執筆中]
Perl manpages Last change: Release 5.0 Patchlevel 00 9
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
二重に型をもつ SV
スカラ変数は、通常、整数、倍精度、ポインタ、リファレンスのい
ずれか 1 つの型をとります。 Perl は、実際のデータに対して、
蓄積されている型から、要求されている型へ、自動的に変換を行な
います。
ある種のスカラ変数は、複数の型のスカラデータを持つようになっ
ています。 たとえば、変数 $! は、errno の数値としての値と、
sys_errlist[] から取り出した同値な文字列を持っています。
SV に複数のデータ値を入れるようにするには、2 つのことをしな
くてはなりません。 スカラ型を別に追加するために、sv_set*v
ルーティンを使用すること。 それから、フラグを設定して Perl
に複数のデータを持っていることを知らせることです。 フラグを
設定するための 4 つのマクロは:
SvIOK_on
SvNOK_on
SvPOK_on
SvROK_on
です。 使用するマクロは、最初にどの sv_set*v ルーティンを呼
ぶのかに関わってきます。 これは、sv_set*v ルーティンはすべ
て、特定のデータ型のビットだけを設定し、他をクリアしてしまう
からです。
たとえば、"dberror" という新しい Perl 変数を作って、エラー値
を数値とメッセージ文字列で持つようにするには、以下のように書
きます:
extern int dberror;
extern char *dberror_list;
SV* sv = perl_get_sv("dberror", TRUE);
sv_setiv(sv, (IV) dberror);
sv_setpv(sv, dberror_list[dberror]);
SvIOK_on(sv);
もし、sv_setiv と sv_setpv の順序が逆であれば、SvIOK_on マク
ロの代わりに、SvPOK_on マクロを呼ばなければなりません。
C プログラムから Perl ルーティンを呼び出す
C プログラムから、Perl サブルーティンを呼び出すために使用す
ることのできるルーティンが 4 つあります。 その 4 つは:
I32 perl_call_sv(SV*, I32);
I32 perl_call_pv(char*, I32);
I32 perl_call_method(char*, I32);
I32 perl_call_argv(char*, I32, register char**);
です。 最もよく使われるはずのものは、perl_call_sv です。
Perl manpages Last change: Release 5.0 Patchlevel 00 10
PERLGUTS(1) USER COMMANDS PERLGUTS(1)
引数 SV* には、呼び出される Perl サブルーティンの名前か、そ
のサブルーティンへのリファレンスを含むものです。 2 番目の引
数は、Perl サブルーティンが返す値があれば、それがどんなもの
かを該当ルーティンに知らせます。
4 つのルーティンはいずれも、サブルーティンが Perl スタック上
に返した引数の数を返します。
これら 4 つのルーティンを使うときには、プログラマが Perl ス
タックを操作しなくてはなりません。 以下のマクロと関数が用意
されています:
dSP
PUSHMARK()
PUTBACK
SPAGAIN
ENTER
SAVETMPS
FREETMPS
LEAVE
XPUSH*()
詳しくは perlcall manpage を参照してください。
Memory Allocation
[執筆中]
AUTHOR
Jeff Okamoto <okamoto@corp.hp.com>
With lots of help and suggestions from Dean Roehrich,
Malcolm Beattie, Andreas Koenig, Paul Hudson, Ilya
Zakharevich, Paul Marquess, and Neil Bowers.
DATE
Version 12: 1994/10/16
Perl manpages Last change: Release 5.0 Patchlevel 00 11