diff options
Diffstat (limited to 'README.EXT')
-rw-r--r-- | README.EXT | 198 |
1 files changed, 97 insertions, 101 deletions
diff --git a/README.EXT b/README.EXT index c2f81d1a7a..7d2d6456c4 100644 --- a/README.EXT +++ b/README.EXT @@ -1,21 +1,16 @@ .\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995 -This document explains how to make extention modules for ruby. +This document explains how to make extention modules for Ruby. 1.Basic knowledge In C, variables have types and data do not have types. In contrast, -ruby variables do not have static type and data themselves have +Ruby variables do not have static type and data themselves have types. So, data need to be converted across the languages. -Data in ruby represented C type `VALUE'. Each VALUE data have its +Data in Ruby represented C type `VALUE'. Each VALUE data have its data-type. -rubyのデータはVALUEというCの型で表現されます.VALUE型のデー -タはそのデータタイプを自分で知っています.このデータタイプと -いうのはデータ(オブジェクト)の実際の構造を意味していて,ruby -のクラスとはまた違ったものです. - To retrieve an C data from the VALUE, you need to: (1) Identify VALUE's data type @@ -38,7 +33,7 @@ Ruby interpreter has data-types as below: T_ARRAY array T_FIXNUM Fixnum(31bit integer) T_HASH assosiative array - T_STRUCT (ruby) structure + T_STRUCT (Ruby) structure T_BIGNUM multi precision integer T_TRUE true T_FALSE false @@ -90,12 +85,12 @@ There are faster check-macros for fixnums and nil. 1.3 Convert VALUE into C data データタイプがT_NIL, T_FALSE, T_TRUEである時,データはそれぞ -れnil, FALSE, TRUEです.このデータタイプのオブジェクトはひと +れnil, false, trueです.このデータタイプのオブジェクトはひと つずつしか存在しません. データタイプがT_FIXNUMの時,これは31bitのサイズを持つ整数で す.FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使 -います.それから,FIXNUMに限らずrubyのデータを整数に変換する +います.それから,FIXNUMに限らずRubyのデータを整数に変換する 「NUM2INT()」というマクロがあります.このマクロはデータタイ プのチェック無しで使えます(整数に変換できない場合には例外が 発生する). @@ -116,7 +111,7 @@ ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文 とします.配列の場合には,それぞれ「RARRAT(str)->len」, 「RARRAT(str)->ptr」となります. -rubyの構造体を直接アクセスする時に気をつけなければならないこ +Rubyの構造体を直接アクセスする時に気をつけなければならないこ とは,配列や文字列の構造体の中身は参照するだけで,直接変更し ないことです.直接変更した場合,オブジェクトの内容の整合性が とれなくなって,思わぬバグの原因になります. @@ -137,10 +132,10 @@ VALUEの実際の構造は うかわかるわけです(ポインタのLSBが立っていないことを仮定して いる). -ですから,FIXNUM以外のrubyのオブジェクトの構造体は単にVALUE +ですから,FIXNUM以外のRubyのオブジェクトの構造体は単にVALUE にキャストするだけでVALUEに変換出来ます.ただし,任意の構造 体がVALUEにキャスト出来るわけではありません.キャストするの -はrubyの知っている構造体(ruby.hで定義されているstruct RXxxx +はRubyの知っている構造体(ruby.hで定義されているstruct RXxxx のもの)だけにしておいてください. FIXNUMに関しては変換マクロを経由する必要があります.Cの整数 @@ -153,11 +148,11 @@ FIXNUMに関しては変換マクロを経由する必要があります.Cの整数 INT2NUM()は整数がFIXNUMの範囲に収まらない場合,Bignumに変換 してくれます(が,少し遅い). -1.5 Manipulate ruby data +1.5 Manipulate Ruby data -先程も述べた通り,rubyの構造体をアクセスする時に内容の更新を -行うことは勧められません.で,rubyのデータを操作する時には -rubyが用意している関数を用いてください. +先程も述べた通り,Rubyの構造体をアクセスする時に内容の更新を +行うことは勧められません.で,Rubyのデータを操作する時には +Rubyが用意している関数を用いてください. ここではもっとも使われるであろう文字列と配列の生成/操作を行 い関数をあげます(全部ではないです). @@ -166,16 +161,16 @@ rubyが用意している関数を用いてください. str_new(char *ptr, int len) - Creates a new ruby string. + Creates a new Ruby string. str_new2(char *ptr) - Creates a new ruby string from C string. This is equivalent to + Creates a new Ruby string from C string. This is equivalent to str_new(ptr, strlen(ptr)). str_cat(VALUE str, char *ptr, int len) - Appends len bytes data from ptr to the ruby string. + Appends len bytes data from ptr to the Ruby string. Array functions @@ -205,17 +200,17 @@ rubyが用意している関数を用いてください. Array operations. The first argument to each functions must be an array. They may dump core if other types given. -2. Extend ruby with C +2. Extend Ruby with C -原理的にrubyで書けることはCでも書けます.rubyそのものがCで記 +原理的にRubyで書けることはCでも書けます.RubyそのものがCで記 述されているんですから,当然といえば当然なんですけど.ここで -はrubyの拡張に使うことが多いだろうと予測される機能を中心に紹 +はRubyの拡張に使うことが多いだろうと予測される機能を中心に紹 介します. -2.1 Add new features to ruby +2.1 Add new features to Ruby -rubyで提供されている関数を使えばrubyインタプリタに新しい機能 -を追加することができます.rubyでは以下の機能を追加する関数が +Rubyで提供されている関数を使えばRubyインタプリタに新しい機能 +を追加することができます.Rubyでは以下の機能を追加する関数が 提供されています. * クラス,モジュール @@ -247,7 +242,7 @@ rubyで提供されている関数を使えばrubyインタプリタに新しい機能 念のため説明すると「特異メソッド」とは,その特定のオブジェク -トに対してだけ有効なメソッドです.rubyではよくSmalltalkにお +トに対してだけ有効なメソッドです.RubyではよくSmalltalkにお けるクラスメソッドとして,クラスに対する特異メソッドが使われ ます. @@ -258,7 +253,7 @@ rubyで提供されている関数を使えばrubyインタプリタに新しい機能 argcが負の時は引数の数ではなく,形式を指定したことになります. argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引 -数はrubyの配列として渡されます. +数はRubyの配列として渡されます. メソッドを定義する関数はもう二つあります.ひとつはprivateメ ソッドを定義する関数で,引数はrb_define_method()と同じです. @@ -304,21 +299,21 @@ privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ 前者は特定のクラス/モジュールに属する定数を定義するもの,後 者はグローバルな定数を定義するものです. -2.2 Use ruby features from C +2.2 Use Ruby features from C -既に『1.5 rubyのデータを操作する』で一部紹介したような関数を -使えば,rubyの機能を実現している関数を直接呼び出すことが出来 +既に『1.5 Rubyのデータを操作する』で一部紹介したような関数を +使えば,Rubyの機能を実現している関数を直接呼び出すことが出来 ます. # このような関数の一覧表はいまのところありません.ソースを見 # るしかないですね. -それ以外にもrubyの機能を呼び出す方法はいくつかあります. +それ以外にもRubyの機能を呼び出す方法はいくつかあります. -2.2.1 rubyのプログラムをevalする +2.2.1 Rubyのプログラムをevalする -Cからrubyの機能を呼び出すもっとも簡単な方法として,文字列で -与えられたrubyのプログラムを評価する関数があります. +CからRubyの機能を呼び出すもっとも簡単な方法として,文字列で +与えられたRubyのプログラムを評価する関数があります. VALUE rb_eval_string(char *str) @@ -327,11 +322,11 @@ Cからrubyの機能を呼び出すもっとも簡単な方法として,文字列で 2.2.2 ID or Symbol -Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま -す.その前に,rubyインタプリタ内でメソッドや変数名を指定する +Cから文字列を経由せずにRubyのメソッドを呼び出すこともできま +す.その前に,Rubyインタプリタ内でメソッドや変数名を指定する 時に使われているIDについて説明しておきましょう. -IDとは変数名,メソッド名を表す整数です.rubyの中では +IDとは変数名,メソッド名を表す整数です.Rubyの中では :識別子 @@ -342,9 +337,9 @@ IDとは変数名,メソッド名を表す整数です.rubyの中では を使います.また一文字の演算子はその文字コードがそのままシン ボルになっています. -2.2.3 Invoke ruby method from C +2.2.3 Invoke Ruby method from C -Cから文字列を経由せずにrubyのメソッドを呼び出すためには以下 +Cから文字列を経由せずにRubyのメソッドを呼び出すためには以下 の関数を使います. VALUE rb_funcall(VALUE recv, ID mid, int argc, ...) @@ -373,13 +368,13 @@ idはrb_intern()で得られるものを使ってください. クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ れている関数を使ってください. -3. Informatin sharing between ruby and C +3. Informatin sharing between Ruby and C -C言語とrubyの間で情報を共有する方法について解説します. +C言語とRubyの間で情報を共有する方法について解説します. -3.1 Ruby constant that Cから参照できるrubyの定数 +3.1 Ruby constant that Cから参照できるRubyの定数 -Following ruby constants can be referred from C. +Following Ruby constants can be referred from C. TRUE FALSE @@ -390,19 +385,19 @@ Boolean values. FALSE is false in the C also (i.e. 0). Ruby nil in C scope. -3.2 Global variables shared between C and ruby +3.2 Global variables shared between C and Ruby -Cとrubyで大域変数を使って情報を共有できます.共有できる大域 +CとRubyで大域変数を使って情報を共有できます.共有できる大域 変数にはいくつかの種類があります.そのなかでもっとも良く使わ れると思われるのはrb_define_variable()です. void rb_define_variable(char *name, VALUE *var) -この関数はrubyとCとで共有する大域変数を定義します.変数名が +この関数はRubyとCとで共有する大域変数を定義します.変数名が `$'で始まらない時には自動的に追加されます.この変数の値を変 -更すると自動的にrubyの対応する変数の値も変わります. +更すると自動的にRubyの対応する変数の値も変わります. -またruby側からは更新できない変数もあります.このread onlyの +またRuby側からは更新できない変数もあります.このread onlyの 変数は以下の関数で定義します. void rb_define_readonly_variable(char *name, VALUE *var) @@ -421,13 +416,13 @@ setterに0を指定します. # getterもsetterも0ならばrb_define_variable()と同じになる. -それから,Cの関数によって実現されるrubyの大域変数を定義する +それから,Cの関数によって実現されるRubyの大域変数を定義する 関数があります. void rb_define_virtual_variable(char *name, VALUE (*getter)(), VALUE (*setter)()) -この関数によって定義されたrubyの大域変数が参照された時には +この関数によって定義されたRubyの大域変数が参照された時には getterが,変数に値がセットされた時にはsetterが呼ばれます. The prototypes of the getter and setter functions are as following: @@ -435,14 +430,14 @@ The prototypes of the getter and setter functions are as following: (*getter)(ID id, void *data, struct global_entry* entry); (*setter)(VALUE val, ID id, void *data, struct global_entry* entry); -3.3 Encapsulate C data into ruby object +3.3 Encapsulate C data into Ruby object -Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして +Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして 取り扱いたい場合がありえます.このような場合には,Dataという -rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby +RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby オブジェクトとして取り扱えるようになります. -Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル +Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル 化するためには,以下のマクロを使います. Data_Wrap_Struct(class,mark,free,ptr) @@ -450,7 +445,7 @@ Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル このマクロの戻り値は生成されたDataオブジェクトです. classはこのDataオブジェクトのクラスです.ptrはカプセル化する -Cの構造体へのポインタです.markはこの構造体がrubyのオブジェ +Cの構造体へのポインタです.markはこの構造体がRubyのオブジェ クトへの参照がある時に使う関数です.そのような参照を含まない 時には0を指定します. @@ -483,14 +478,14 @@ Cの構造体へのポインタは変数svalに代入されます. 4.Example - Create dbm module ここまでの説明でとりあえず拡張モジュールは作れるはずです. -rubyのextディレクトリにすでに含まれているdbmモジュールを例に +Rubyのextディレクトリにすでに含まれているdbmモジュールを例に して段階的に説明します. (1) make the directory % mkdir ext/dbm -rubyを展開したディレクトリの下,extディレクトリの中に拡張モ +Rubyを展開したディレクトリの下,extディレクトリの中に拡張モ ジュール用のディレクトリを作ります.名前は適当に選んで構いま せん. @@ -522,7 +517,7 @@ MANIFESTというファイルは,makeの時にディレクトリが拡張モジュー ル生成時に中間的に生成される「モジュール名.o」というファイル とが衝突するからです. -rubyは拡張モジュールをロードする時に「Init_モジュール名」と +Rubyは拡張モジュールをロードする時に「Init_モジュール名」と いう関数を自動的に実行します.dbmモジュールの場合「Init_dbm」 です.この関数の中でクラス,モジュール,メソッド,定数などの 定義を行います.dbm.cから一部引用します. @@ -550,7 +545,7 @@ Init_dbm() -- DBMモジュールはdbmのデータと対応するオブジェクトになるはずで -すから,Cの世界のdbmをrubyの世界に取り込む必要があります. +すから,Cの世界のdbmをRubyの世界に取り込む必要があります. dbm.cではData_Make_Structを以下のように使っています. @@ -600,7 +595,7 @@ fdbm_delete(obj, keystr) 引数の数が固定のタイプは第1引数がself,第2引数以降がメソッド の引数となります. -引数の数が不定のものはCの配列で受けるものとrubyの配列で受け +引数の数が不定のものはCの配列で受けるものとRubyの配列で受け るものとがあります.dbmモジュールの中で,Cの配列で受けるもの はDBMのクラスメソッドであるopen()です.これを実装している関 数fdbm_s_open()はこうなっています. @@ -634,7 +629,7 @@ fdbm_s_open(argc, argv, class) で,2つまで許されるという意味になります.省略されている時の 変数の値はnil(C言語のレベルではQnil)になります. -rubyの配列で引数を受け取るものはindexesがあります.実装はこ +Rubyの配列で引数を受け取るものはindexesがあります.実装はこ うです. -- @@ -647,14 +642,14 @@ fdbm_indexes(obj, args) } -- -第1引数はself,第2引数はrubyの配列です.ここではキャストを減 +第1引数はself,第2引数はRubyの配列です.ここではキャストを減 らすため struct RArray* で受けていますが,VALUEでも同じこと です. ** 注意事項 -rubyと共有はしないがrubyのオブジェクトを格納する可能性のある -Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在 +Rubyと共有はしないがRubyのオブジェクトを格納する可能性のある +Cの大域変数は以下の関数を使ってRubyインタプリタに変数の存在 を教えてあげてください.でないとGCでトラブルを起こします. void rb_global_variable(VALUE *var) @@ -665,7 +660,7 @@ Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在 make時に実行されます.なければ適当にMakefileが生成されます. extconf.rbはモジュールのコンパイルに必要な条件のチェックなど -を行うことが目的です.extconf.rbの中では以下のruby関数を使う +を行うことが目的です.extconf.rbの中では以下のRuby関数を使う ことが出来ます. have_library(lib, func): ライブラリの存在チェック @@ -704,31 +699,31 @@ make時にはMANIFESTの内容は参照しませんので,空のままでも問題 (8) make -rubyのディレクトリでmakeを実行するとMakefileを生成からmake, -必要によってはそのモジュールのrubyへのリンクまで自動的に実行 +Rubyのディレクトリでmakeを実行するとMakefileを生成からmake, +必要によってはそのモジュールのRubyへのリンクまで自動的に実行 してくれます.extconf.rbを書き換えるなどしてMakefileの再生成 -が必要な時はまたrubyディレクトリでmakeしてください. +が必要な時はまたRubyディレクトリでmakeしてください. (9) debug -まあ,デバッグしないと動かないでしょうね.ext/Setupにディレ -クトリ名を書くと静的にリンクするのでデバッガが使えるようにな -ります.その分コンパイルが遅くなりますけど. +You may need to debug the module. The modules can be linked +statically by adding directory name in the ext/Setup file, +so that you can inspect the module by the debugger. (10) done, now you have the extension module 後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお -使いください.rubyの作者は拡張モジュールに関して一切の権利を +使いください.Rubyの作者は拡張モジュールに関して一切の権利を 主張しません. -Appendix A. rubyのソースコードの分類 +Appendix A. Rubyのソースコードの分類 -rubyのソースはいくつかに分類することが出来ます.このうちクラ +Rubyのソースはいくつかに分類することが出来ます.このうちクラ スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ ています.これらのソースは今までの説明でほとんど理解できると 思います. -coore ruby language +ruby language core class.c error.c @@ -780,13 +775,13 @@ class library Appendix B. 拡張用関数リファレンス -C言語からrubyの機能を利用するAPIは以下の通りである. +C言語からRubyの機能を利用するAPIは以下の通りである. ** 型 VALUE -rubyオブジェクトを表現する型.必要に応じてキャストして用いる. +Rubyオブジェクトを表現する型.必要に応じてキャストして用いる. 組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造 体である.VALUE型をこれらにキャストするためにRで始まる構造体 名を全て大文字にした名前のマクロが用意されている. @@ -809,9 +804,9 @@ const: FALSE object Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval) -Cの任意のポインタをカプセル化したrubyオブジェクトを返す.こ -のポインタがrubyからアクセスされなくなった時,freeで指定した -関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ +Cの任意のポインタをカプセル化したRubyオブジェクトを返す.こ +のポインタがRubyからアクセスされなくなった時,freeで指定した +関数が呼ばれる.また,このポインタの指すデータが他のRubyオブ ジェクトを指している場合,markに指定する関数でマークする必要 がある. @@ -828,20 +823,20 @@ dataからtype型のポインタを取り出し変数svalに代入するマクロ. VALUE rb_define_class(char *name, VALUE super) -superのサブクラスとして新しいrubyクラスを定義する. +superのサブクラスとして新しいRubyクラスを定義する. VALUE rb_define_class_under(VALUE module, char *name, VALUE super) -superのサブクラスとして新しいrubyクラスを定義し,moduleの定 +superのサブクラスとして新しいRubyクラスを定義し,moduleの定 数として定義する. VALUE rb_define_module(char *name) -新しいrubyモジュールを定義する. +新しいRubyモジュールを定義する. VALUE rb_define_module_under(VALUE module, char *name, VALUE super) -新しいrubyモジュールを定義し,moduleの定数として定義する. +新しいRubyモジュールを定義し,moduleの定数として定義する. void rb_include_module(VALUE class, VALUE module) @@ -856,20 +851,20 @@ superのサブクラスとして新しいrubyクラスを定義し,moduleの定 void rb_define_variable(char *name, VALUE *var) -rubyとCとで共有するグローバル変数を定義する.変数名が`$'で始 -まらない時には自動的に追加される.nameとしてrubyの識別子とし -て許されない文字(例えば` ')を含む場合にはrubyプログラムから +RubyとCとで共有するグローバル変数を定義する.変数名が`$'で始 +まらない時には自動的に追加される.nameとしてRubyの識別子とし +て許されない文字(例えば` ')を含む場合にはRubyプログラムから は見えなくなる. void rb_define_readonly_variable(char *name, VALUE *var) -rubyとCとで共有するread onlyのグローバル変数を定義する.read +RubyとCとで共有するread onlyのグローバル変数を定義する.read onlyであること以外はrb_define_variable()と同じ. void rb_define_virtual_variable(char *name, VALUE (*getter)(), VALUE (*setter)()) -関数によって実現されるruby変数を定義する.変数が参照された時 +関数によって実現されるRuby変数を定義する.変数が参照された時 にはgetterが,変数に値がセットされた時にはsetterが呼ばれる. void rb_define_hooked_variable(char *name, VALUE *var, @@ -882,7 +877,7 @@ onlyであること以外はrb_define_variable()と同じ. void rb_global_variable(VALUE *var) -GCのため,rubyプログラムからはアクセスされないが, rubyオブジェ +GCのため,Rubyプログラムからはアクセスされないが, Rubyオブジェ クトを含む大域変数をマークする. ** クラス定数 @@ -906,7 +901,7 @@ GCのため,rubyプログラムからはアクセスされないが, rubyオブジェ メソッドを定義する.argcはselfを除く引数の数.argcが-1の時, 関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引 数とする形式で与えられる(第3引数はself).argcが-2の時, 第1引 -数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形 +数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形 式で与えられる. rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc) @@ -927,7 +922,7 @@ argc,argv形式で与えられた引数を分解する.fmtは必須引数の数, 数に対応する引数が与えられていない場合は変数にQnilが代入され る. -** rubyメソッド呼び出し +** Rubyメソッド呼び出し VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) @@ -939,7 +934,7 @@ argc,argv形式で与えられた引数を分解する.fmtは必須引数の数, VALUE rb_eval_string(char *str) -文字列をrubyとスクリプトしてコンパイル・実行する. +文字列をRubyとスクリプトしてコンパイル・実行する. ID rb_intern(char *name) @@ -959,7 +954,7 @@ classの名前を返す(デバッグ用).classが名前を持たない時には, VALUE rb_iv_get(VALUE obj, char *name) objのインスタンス変数の値を得る.`@'で始まらないインスタンス -変数は rubyプログラムからアクセスできない「隠れた」インスタ +変数は Rubyプログラムからアクセスできない「隠れた」インスタ ンス変数になる. VALUE rb_iv_set(VALUE obj, char *name, VALUE val) @@ -1013,22 +1008,23 @@ verbose時に標準エラー出力に警告情報を表示する.引数はprintf()と同じ. 況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外 処理は一切行なわれない. -** rubyの初期化・実行 +** Rubyの初期化・実行 -rubyをアプリケーションに埋め込む場合には以下のインタフェース +Rubyをアプリケーションに埋め込む場合には以下のインタフェース を使う.通常の拡張モジュールには必要ない. void ruby_init(int argc, char **argv, char **envp) -rubyインタプリタの初期化を行なう. +Rubyインタプリタの初期化を行なう. void ruby_run() -rubyインタプリタを実行する. +Rubyインタプリタを実行する. void ruby_script(char *name) -rubyのスクリプト名($0)を設定する. +Rubyのスクリプト名($0)を設定する. + Appendix B. extconf.rbで使える関数たち |