ささだです.

(2012/06/15 16:30), Yugui wrote:
>> ...
>>> +/**
>>> + * @defgroup embed CRuby Embedding APIs
>>> + * CRuby interpreter APIs. These are APIs to embed MRI interpreter into your
>>> + * program.
>>> + * These functions are not a part of Ruby extention library API.
>>> + * Extension libraries of Ruby should not depend on these functions.
>>> + * @{
>>> + */
>>> +
>>> +/*! Opaque pointer to an inner data structure.
>>> + *
>>> + * You do not have to know what the actual data type this pointer points.
>>> + * It often changes for internal improvements.
>>> + */
>>> +typedef void *ruby_opaque_t;
>>
>> そのまま void * じゃ駄目なんでしたっけ? 今,void * と混ざっているよう
>> ですが.
> 
> 何でvoid*なのか一瞬考えたことがあったので、明示するのは悪くないと思います。
> 混ざってるならそれは見落としですね。

 個人的には,opaque ってなんじゃらと混乱しましたので,よくわからんポイ
ンタだとわかる void * のほうが好きなのですが.hoge_opaque_t ってのは,よ
く知られた表現なんですかね?

 この辺は,bikeshed になるでしょうか.どうしたもんですかね.


>>  構成的には,
>>
>> - 必須な項目
>> - optional な項目
>>
>> の順番に並んでいた方がいいかと思います.が,そういうのはヘッダじゃなくて
>> なんか README.embedded みたいなのを書くのが筋だろうか.
> 
> ですねー。それ欲しいですね。

 先に,これがあったほうが,実はアプリケーション組み込み用のデザインがや
りやすいかもしれません.


>>> +void ruby_sysinit(int *argc, char ***argv);
>>> +void ruby_init(void);
>>> +ruby_opaque_t ruby_options(int argc, char** argv);
>>> +int ruby_executable_node(ruby_opaque_t n, int *status);
>>> +int ruby_run_node(ruby_opaque_t n);
>>> +
>>> +/* version.c */
>>> +void ruby_show_version(void);
>>> +void ruby_show_copyright(void);
>>
>>  version とかって,これは埋め込みのためなんだろうか.
> 
> Matzのcopyrightを表示したいというニーズはどこかにあるんじゃないですかね。
> 少なくともextのためのものではないので。
> 
> extのためのものでないAPIを一まとめにしてみました。

 了解です.


> ですです。使う必要が無いなら隠しても良いですが、互換性への配慮は必要ですね。
> とりあえずdeprecated attributeでも付けてみますか?

 この辺は別件として整理するべきでしょうか.


>>> +ruby_opaque_t ruby_compile_main_from_file(VALUE fname, const char* path, VALUE* error);
>>> +ruby_opaque_t ruby_compile_main_from_string(VALUE fname, VALUE string, VALUE* error);
>>
>>  コンパイルって要りますかね.eval だけじゃ駄目なんでしたっけ.つまり,
>> ファイル名,もしくは文字列渡して実行するインターフェースだけだと不十分?

 この点についてはどうでしょうか.

 IRCNet#ruby-ja で,

> 16:55 yugui      > 同じ式を繰り返し評価したいニーズは埋め込みでは結構
あるので

ということで,使い回したい,ということかと思うのですが,

(1) 使い回すならメソッドとして定義したほうがよさそう
(2) コンパイルするコストは本当に問題か?

というのが気になります.これが無くなると,iseq を見せなくてよさそうだか
ら(opaque ってなんだろうと思わなくて済むので),評価までやっちゃったほ
うがいいじゃないかな,と思っています.


>>  ファイル名を渡すなら,ruby_options でファイル名渡せば main で実行され
>> ますんで,文字列で実行する版だけがあればよい?
> 
> オプション解析がまったく余分です。

 余分であって,出来ないわけじゃないですよね.困る場合はあるでしょう
か.1つ思いついたのは,ファイル名を正しくクオートした文字列として渡さな
いといけないのが困るかな,という点でした.

 現状,Ruby への起動インターフェースをまとめたもの,ということかと思っ
ています.


>>> +int ruby_exec_node(ruby_opaque_t n);
>>> +int ruby_eval_main(ruby_opaque_t n, VALUE *result);
>>
>>  eval_main というのが適切か自信がありません.eval_in_main_context とか
>> だと冗長でしょうか.
> 
> それでもいいかもしれません。

 あと,Kernel.eval というのは文字列をとるので,iseq を受け取るインター
フェースは混乱しそうな気がします(なので,上で述べた文字列を受け取り評価
までするほうがいいんじゃないかな,と思っています).


>>> Index: eval.c
>>> ===================================================================
>>> --- eval.c    (revision 36078)
>>> +++ eval.c    (revision 36079)
>> ...
>>> +/* Initializes the Ruby VM and builtin libraries.
>>> + * @retval 0 if succeeded.
>>> + * @retval non-zero an error occured.
>>> + */
>>> +int
>>> +ruby_setup(void)
>>>  {
>>
>>  0 が成功ってのは,ほかもありましたっけ.
> 
> この辺の関数は全部exit(3)に渡す前提なので0が成功ですね。

 了解です.

 気になったのが,内部で使う分には「気を付けよう」で済むのが,外部へ出す
となると,0失敗,1成功,のほうがわかりやすいかな,と思ったのでした.

 返値を ruby_exit_code_t という型にすると,ちょっとわかりやすくなるかも
しれませんね.


-- 
// SASADA Koichi at atdot dot net