2012/6/15 SASADA Koichi <ko1 / atdot.net>:
>  ささだです.
>
> (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 ってのは,よ
> く知られた表現なんですかね?

opaque pointerってのはよくある表現ですよね。

>
>  この辺は,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 を受け取るインター
> フェースは混乱しそうな気がします(なので,上で述べた文字列を受け取り評価
> までするほうがいいんじゃないかな,と思っています).

コンパイルコストが本当に必要になるケースがはっきりしてくるまでは、まずはそれで良いかもしれません。
じゃ、ruby_compile_main_from_string と ruby_eval_main は削除しましょう。

ここで案が2つあります。
1. toplevel_binding と rb_f_evalを公開する
2. さらに両者を合わせてruby_eval_in_main みたいなのを作る。

どっちが良いと思います?
ちなみに、いずれにしてもさらにファイル版は必要だと思います。というのはマジックコメントとか読んで
適切なエンコーディングを付けたりってのは結構面倒なので。
で、そのエンコーディングを付ける話を始めるとまたencdet話に跳んでしまうので、
* rb_eval_string_in_main
* rb_eval_file_in_main
を作るのが現実的かなと思ってます。

>
>
>>>> 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
>



-- 
Yuki Sonoda (Yugui)
yugui / yugui.jp
http://yugui.jp