mruby/C構造体組み込みを読む
をテンプレートにして作成
[
トップ
] [
新規
|
一覧
|
単語検索
|
最終更新
|
ヘルプ
]
開始行:
[[mrubyを読む]]
#contents
*はじめに [#wd417a91]
最近、mrubyのAPIを使うサンプルを書こうとしているのですが...
*クラスの定義 [#c6da9ce0]
というわけで、src/time.cのmrb_init_time()を見ていきましょ...
#code(C){{
struct RClass *tc;
/* ISO 15.2.19.2 */
tc = mrb_define_class(mrb, "Time", mrb->object_class);
MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA);
mrb_include_module(mrb, tc, mrb_class_get(mrb, "Compara...
}}
クラスを定義するにはmrb_define_class()を利用します。第2引...
クラスにモジュールをインクルードする場合はmrb_include_mod...
*メソッドの定義 [#p70f1446]
ではメソッドの定義に進みます。
#code(C){{
mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARG...
mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARG...
mrb_define_class_method(mrb, tc, "local", mrb_time_loca...
mrb_define_class_method(mrb, tc, "mktime", mrb_time_loc...
mrb_define_class_method(mrb, tc, "now", mrb_time_now, A...
mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, AR...
}}
クラスメソッドの定義はmrb_define_class_method()で行います...
第5引数はメソッドの引数情報で、
:ARGS_ANY()|任意の引数を取る
:ARGS_REQ(1)|ARGS_OPT(6)|1つの引数は必須でオプション...
:ARGS_NONE()|引数なし
という意味になります。((じつは、2012/7/22現在この情報は使...
次にインスタンスメソッドの定義です。利用するAPIがmrb_defi...
#code(C){{
mrb_define_method(mrb, tc, "==" , mrb_time_eq ,...
mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp ,...
(以下省略)
}}
*インスタンスの生成 [#r0632cad]
次はインスタンスの生成です。Time.nowの実装であるmrb_time_...
#code(C){{
static mrb_value
mrb_time_now(mrb_state *mrb, mrb_value self)
{
return mrb_time_wrap(mrb, mrb_class_ptr(self), current_...
}
}}
mrubyでのメソッドを実装する関数のシグネチャについてはまた...
currrent_mrb_time()は実際にはgettimeofday()があるかどうか...
#code(C){{
static struct mrb_time*
current_mrb_time(mrb_state *mrb)
{
struct mrb_time *tm;
tm = mrb_malloc(mrb, sizeof(*tm));
{
struct timeval tv;
gettimeofday(&tv, NULL);
tm->sec = tv.tv_sec;
tm->usec = tv.tv_usec;
}
tm->timezone = MRB_TIMEZONE_LOCAL;
mrb_time_update_datetime(tm);
return tm;
}
}}
メモリ確保はmrb_malloc()を使います。
#code(C){{
static mrb_value
mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct m...
{
return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_tim...
}
}}
インスタンスの生成はData_Wrap_Structマクロを使います。mrb...
#code(C){{
static struct mrb_data_type mrb_time_type = { "Time", mrb...
}}
というわけで構造体名とGCで解放されるときに使われるfree関...
*メソッドの実装 [#a9a00313]
続いてメソッド実装を見てみましょう。Time#<=>(other)の実装...
#code(C){{
static mrb_value
mrb_time_cmp(mrb_state *mrb, mrb_value self)
{
mrb_value other;
struct mrb_time *tm1, *tm2;
mrb_get_args(mrb, "o", &other);
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_nil_value();
if (tm1->sec > tm2->sec) {
return mrb_fixnum_value(1);
}
else if (tm1->sec < tm2->sec) {
return mrb_fixnum_value(-1);
}
/* tm1->sec == tm2->sec */
if (tm1->usec > tm2->usec) {
return mrb_fixnum_value(1);
}
else if (tm1->usec < tm2->usec) {
return mrb_fixnum_value(-1);
}
return mrb_fixnum_value(0);
}
}}
まずは先ほど前振りしたメソッド実装関数のシグネチャについ...
**メソッド引数の取得 [#ud5b6457]
メソッドの引数を取得する場合はmrb_get_args()を使用します...
#code(C){{
/*
retrieve arguments from mrb_state.
mrb_get_args(mrb, format, ...)
returns number of arguments parsed.
fortmat specifiers:
o: Object [mrb_value]
S: String [mrb_value]
A: Array [mrb_value]
H: Hash [mrb_value]
s: String [char*,int]
z: String [char*]
a: Array [mrb_value*,int]
f: Float [mrb_float]
i: Integer [mrb_int]
n: Symbol [mrb_sym]
&: Block [mrb_value]
*: rest argument [mrb_value*,int]
|: optional
*/
}}
引数情報中に'|'を含めるとオプション引数が実現できます。オ...
#code(C){{
static mrb_value
mrb_time_local(mrb_state *mrb, mrb_value self)
{
mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, ami...
mrb_get_args(mrb, "i|iiiiii",
&ayear, &amonth, &aday, &ahour, &amin, &a...
return mrb_time_wrap(mrb, mrb_class_ptr(self),
time_mktime(mrb, ayear, amonth, aday, ahour, ami...
}
}}
**C構造体の取得 [#gbbcacd1]
オブジェクトからC構造体を取り出すにはmrb_get_datatype()を...
#code(C){{
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_nil_value();
}}
上記のように第2引数に構造体を取り出すオブジェクト、第3引...
ところで、voidポインタってキャストしなくても怒られないん...
**戻り値の返却 [#lbf1acab]
メソッドの戻り値はmrb_value型を返します。
#code(C){{
if (tm1->sec > tm2->sec) {
return mrb_fixnum_value(1);
}
else if (tm1->sec < tm2->sec) {
return mrb_fixnum_value(-1);
}
/* tm1->sec == tm2->sec */
if (tm1->usec > tm2->usec) {
return mrb_fixnum_value(1);
}
else if (tm1->usec < tm2->usec) {
return mrb_fixnum_value(-1);
}
return mrb_fixnum_value(0);
}}
整数をmrb_valueにするにはmrb_fixnum_value()を使用します。...
*APIまとめ [#s859e253]
最後にクラス定義・実装に利用するAPIをまとめておきます。一...
:struct RClass * mrb_class_get(mrb_state *mrb, const char...
:struct RClass *mrb_define_module(mrb_state *mrb, const c...
:struct RClass *mrb_define_class(mrb_state *mrb, const ch...
:struct RClass * mrb_define_class_under(mrb_state *mrb, s...
:void mrb_include_module(mrb_state *mrb, struct RClass *c...
:void mrb_define_const(mrb_state *mrb, struct RClass *mod...
:void mrb_define_method(mrb_state *mrb, struct RClass *c,...
:void mrb_define_class_method(mrb_state *mrb, struct RCla...
void
:void mrb_define_module_function(mrb_state *mrb, struct R...
:struct RClass *mrb_class_ptr(mrb_object klass);|mrb_obje...
:struct RData* Data_Wrap_Struct(mrb_state *mrb, struct RC...
:mrb_value mrb_obj_value(void *p);|オブジェクト構造体への...
:int mrb_get_args(mrb_state *mrb, const char *format, ......
:void *mrb_get_datatype(mrb_state *mrb, mrb_value obj, co...
:mrb_value mrb_fixnum_value(mrb_int i);|整数をオブジェク...
:mrb_value mrb_float_value(mrb_float f);|浮動小数点数をオ...
:mrb_value mrb_true_value(void);|trueを表すオブジェクトを...
:mrb_value mrb_false_value(void);|falseを表すオブジェクト...
:mrb_value mrb_nil_value(void);|nilを表すオブジェクトを返...
*おわりに [#vc40a353]
今回はmruby APIのサンプルということでAPI実装の中身にはあ...
終了行:
[[mrubyを読む]]
#contents
*はじめに [#wd417a91]
最近、mrubyのAPIを使うサンプルを書こうとしているのですが...
*クラスの定義 [#c6da9ce0]
というわけで、src/time.cのmrb_init_time()を見ていきましょ...
#code(C){{
struct RClass *tc;
/* ISO 15.2.19.2 */
tc = mrb_define_class(mrb, "Time", mrb->object_class);
MRB_SET_INSTANCE_TT(tc, MRB_TT_DATA);
mrb_include_module(mrb, tc, mrb_class_get(mrb, "Compara...
}}
クラスを定義するにはmrb_define_class()を利用します。第2引...
クラスにモジュールをインクルードする場合はmrb_include_mod...
*メソッドの定義 [#p70f1446]
ではメソッドの定義に進みます。
#code(C){{
mrb_define_class_method(mrb, tc, "at", mrb_time_at, ARG...
mrb_define_class_method(mrb, tc, "gm", mrb_time_gm, ARG...
mrb_define_class_method(mrb, tc, "local", mrb_time_loca...
mrb_define_class_method(mrb, tc, "mktime", mrb_time_loc...
mrb_define_class_method(mrb, tc, "now", mrb_time_now, A...
mrb_define_class_method(mrb, tc, "utc", mrb_time_gm, AR...
}}
クラスメソッドの定義はmrb_define_class_method()で行います...
第5引数はメソッドの引数情報で、
:ARGS_ANY()|任意の引数を取る
:ARGS_REQ(1)|ARGS_OPT(6)|1つの引数は必須でオプション...
:ARGS_NONE()|引数なし
という意味になります。((じつは、2012/7/22現在この情報は使...
次にインスタンスメソッドの定義です。利用するAPIがmrb_defi...
#code(C){{
mrb_define_method(mrb, tc, "==" , mrb_time_eq ,...
mrb_define_method(mrb, tc, "<=>" , mrb_time_cmp ,...
(以下省略)
}}
*インスタンスの生成 [#r0632cad]
次はインスタンスの生成です。Time.nowの実装であるmrb_time_...
#code(C){{
static mrb_value
mrb_time_now(mrb_state *mrb, mrb_value self)
{
return mrb_time_wrap(mrb, mrb_class_ptr(self), current_...
}
}}
mrubyでのメソッドを実装する関数のシグネチャについてはまた...
currrent_mrb_time()は実際にはgettimeofday()があるかどうか...
#code(C){{
static struct mrb_time*
current_mrb_time(mrb_state *mrb)
{
struct mrb_time *tm;
tm = mrb_malloc(mrb, sizeof(*tm));
{
struct timeval tv;
gettimeofday(&tv, NULL);
tm->sec = tv.tv_sec;
tm->usec = tv.tv_usec;
}
tm->timezone = MRB_TIMEZONE_LOCAL;
mrb_time_update_datetime(tm);
return tm;
}
}}
メモリ確保はmrb_malloc()を使います。
#code(C){{
static mrb_value
mrb_time_wrap(mrb_state *mrb, struct RClass *tc, struct m...
{
return mrb_obj_value(Data_Wrap_Struct(mrb, tc, &mrb_tim...
}
}}
インスタンスの生成はData_Wrap_Structマクロを使います。mrb...
#code(C){{
static struct mrb_data_type mrb_time_type = { "Time", mrb...
}}
というわけで構造体名とGCで解放されるときに使われるfree関...
*メソッドの実装 [#a9a00313]
続いてメソッド実装を見てみましょう。Time#<=>(other)の実装...
#code(C){{
static mrb_value
mrb_time_cmp(mrb_state *mrb, mrb_value self)
{
mrb_value other;
struct mrb_time *tm1, *tm2;
mrb_get_args(mrb, "o", &other);
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_nil_value();
if (tm1->sec > tm2->sec) {
return mrb_fixnum_value(1);
}
else if (tm1->sec < tm2->sec) {
return mrb_fixnum_value(-1);
}
/* tm1->sec == tm2->sec */
if (tm1->usec > tm2->usec) {
return mrb_fixnum_value(1);
}
else if (tm1->usec < tm2->usec) {
return mrb_fixnum_value(-1);
}
return mrb_fixnum_value(0);
}
}}
まずは先ほど前振りしたメソッド実装関数のシグネチャについ...
**メソッド引数の取得 [#ud5b6457]
メソッドの引数を取得する場合はmrb_get_args()を使用します...
#code(C){{
/*
retrieve arguments from mrb_state.
mrb_get_args(mrb, format, ...)
returns number of arguments parsed.
fortmat specifiers:
o: Object [mrb_value]
S: String [mrb_value]
A: Array [mrb_value]
H: Hash [mrb_value]
s: String [char*,int]
z: String [char*]
a: Array [mrb_value*,int]
f: Float [mrb_float]
i: Integer [mrb_int]
n: Symbol [mrb_sym]
&: Block [mrb_value]
*: rest argument [mrb_value*,int]
|: optional
*/
}}
引数情報中に'|'を含めるとオプション引数が実現できます。オ...
#code(C){{
static mrb_value
mrb_time_local(mrb_state *mrb, mrb_value self)
{
mrb_int ayear = 0, amonth = 1, aday = 1, ahour = 0, ami...
mrb_get_args(mrb, "i|iiiiii",
&ayear, &amonth, &aday, &ahour, &amin, &a...
return mrb_time_wrap(mrb, mrb_class_ptr(self),
time_mktime(mrb, ayear, amonth, aday, ahour, ami...
}
}}
**C構造体の取得 [#gbbcacd1]
オブジェクトからC構造体を取り出すにはmrb_get_datatype()を...
#code(C){{
tm1 = mrb_get_datatype(mrb, self, &mrb_time_type);
tm2 = mrb_get_datatype(mrb, other, &mrb_time_type);
if (!tm1 || !tm2) return mrb_nil_value();
}}
上記のように第2引数に構造体を取り出すオブジェクト、第3引...
ところで、voidポインタってキャストしなくても怒られないん...
**戻り値の返却 [#lbf1acab]
メソッドの戻り値はmrb_value型を返します。
#code(C){{
if (tm1->sec > tm2->sec) {
return mrb_fixnum_value(1);
}
else if (tm1->sec < tm2->sec) {
return mrb_fixnum_value(-1);
}
/* tm1->sec == tm2->sec */
if (tm1->usec > tm2->usec) {
return mrb_fixnum_value(1);
}
else if (tm1->usec < tm2->usec) {
return mrb_fixnum_value(-1);
}
return mrb_fixnum_value(0);
}}
整数をmrb_valueにするにはmrb_fixnum_value()を使用します。...
*APIまとめ [#s859e253]
最後にクラス定義・実装に利用するAPIをまとめておきます。一...
:struct RClass * mrb_class_get(mrb_state *mrb, const char...
:struct RClass *mrb_define_module(mrb_state *mrb, const c...
:struct RClass *mrb_define_class(mrb_state *mrb, const ch...
:struct RClass * mrb_define_class_under(mrb_state *mrb, s...
:void mrb_include_module(mrb_state *mrb, struct RClass *c...
:void mrb_define_const(mrb_state *mrb, struct RClass *mod...
:void mrb_define_method(mrb_state *mrb, struct RClass *c,...
:void mrb_define_class_method(mrb_state *mrb, struct RCla...
void
:void mrb_define_module_function(mrb_state *mrb, struct R...
:struct RClass *mrb_class_ptr(mrb_object klass);|mrb_obje...
:struct RData* Data_Wrap_Struct(mrb_state *mrb, struct RC...
:mrb_value mrb_obj_value(void *p);|オブジェクト構造体への...
:int mrb_get_args(mrb_state *mrb, const char *format, ......
:void *mrb_get_datatype(mrb_state *mrb, mrb_value obj, co...
:mrb_value mrb_fixnum_value(mrb_int i);|整数をオブジェク...
:mrb_value mrb_float_value(mrb_float f);|浮動小数点数をオ...
:mrb_value mrb_true_value(void);|trueを表すオブジェクトを...
:mrb_value mrb_false_value(void);|falseを表すオブジェクト...
:mrb_value mrb_nil_value(void);|nilを表すオブジェクトを返...
*おわりに [#vc40a353]
今回はmruby APIのサンプルということでAPI実装の中身にはあ...
ページ名: