理系学生日記

おまえはいつまで学生気分なのか

perlguts を読んでみてるところ

休日にまとめてエントリを書くと,全部 PerlSICP ですね!
どうも,perlxs を読む前に perlguts を読んだ方がいいっぽいので,今日はずっと perlguts を読んでみたいとおもっています.guts てなんだ.

Perl には 3 種類のデータ型が typedef されています.

  • SV (Scalar)
  • AV (Array)
  • HV (Hash)

しかしながら,他にもあって,

  • IV (Signed Integer; じつはポインタも持てる?)
  • UV (Unsigned Integer)
  • I32,I16
  • U32,U16 (それぞれ32,16 ビット長以上の(たぶん) Unsigned Integer)
  • NV (double)
  • PV (String)

とかある.

SV は他のデータ型から作成するとができるみたいです.この他のデータ型からの作成を,perlguts では load と呼んでいるっぽい.

An SV can be created and loaded with one command.

例えば IV から SV* への変換は newSViv( IV ) という関数で行えるみたいです.同様に,UV や double からの関数も用意されてます.SV は上の文章の通り何も無いところから作成するときもできて,それは newSV( len ) で行う.len は記憶領域のバイト数みたい.

SV *sv = newSV(0);   /* no storage allocated  */
SV *sv = newSV(10);  /* 10 (+1) bytes of uninitialised storage allocated  */

SV の値を変更するためには,何のデータ型を SV にセットするのかによって呼び出す関数が違う.こうやって,動的型付けが提供されているんだなー.

void sv_setiv(SV*, IV);
void sv_setuv(SV*, UV);
void sv_setnv(SV*, double);
void sv_setpv(SV*, const char*);
void sv_setpvn(SV*, const char*, STRLEN)
void sv_setpvf(SV*, const char*, ...);
void sv_vsetpvfn(SV*, const char*, STRLEN, va_list *, SV **, I32, bool *);
void sv_setsv(SV*, SV*);

プロトタイプを見ると,SV* の指す先を変更しているみたい.Shibuya.pm (XS Nite) でもそんなことを聞いた.

じゃぁその SV* が指す SV の値を Get するにはどうすれば! それをやってくれるのが以下のマクロ.

SvIV(SV*)
SvUV(SV*)
SvNV(SV*)
SvPV(SV*, STRLEN len)
SvPV_nolen(SV*)

SvPV て返ってくる文字列の長さを len で制御できるみたいなんだけど,長さがなんぼでもいいときは,SvPV_nolen を使うと.なるほど.
あと,こんな呼び出しはやめたほうが良いっぽい.評価順序が微妙なのかな.

foo(SvPV(s, len), len);

SV* の指す先が true なのか false なのかを調べるのは

SvTRUE(SV*)

SV にもっと大きなメモリを自分で割り当てるときは

SvGROW(SV*, STRLEN newlen)

SV の持っているデータ型のチェックは

SvIOK(SV*)
SvNOK(SV*)
SvPOK(SV*)

を使う.

SV が持っている文字列の長さを Get/Set するのは以下の関数.あれ,これで strlen できるんじゃね?

SvCUR(SV*)
SvCUR_set(SV*, I32 val)
SvEnd(SV*)

は文字列の最後をさすポインタを取得する.