From: SASADA Koichi Date: 2012-06-19T04:49:53+09:00 Subject: [ruby-dev:45762] Re: [ruby-changes:24028] yugui:r36079 (trunk): Embedding CRuby interpreter without internal headers has been difficult  ささだです. (2012/06/15 16:30), Yugui wrote: >> >> +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 だけじゃ駄目なんでしたっけ.つまり, >> ファイル名,もしくは文字列渡して実行するインターフェースだけだと不十分?  余談ですが,このアプローチは根本的に不味いと言うことに気づきました.  Kernel.eval(src, TOPLEVEL_BINDING) 相当を目指していると思うのですが, このために src から作る iseq は,実は渡した TOPLEVEL_BINDING の状態に応 じて異なります.  例で示します. src = "a = 1" という場合,a というローカル変数へ代入というとても簡単なコードなんですが, b = binding eval(src, b) # この時は,自分の環境に a を作るので, # setdynamic(i_idx, 0) という命令になる eval("x = 1", b) # 新しい変数 x が加わるので,b の環境が増える eval(src, b) # 2 つ上の環境の a へ値をセットするので # setdynamic(i_idx, 2) という命令になる  同じスクリプトをコンパイルしていますが,b の状態に応じてコンパイル結果 が異なっています. ※マルチスレッドとか考えたくないですね....  というわけで,コンパイル結果を保存して再利用,というのは原理的に無理で した.  [ruby-dev:45761] で述べた rb_eval_string() だと,環境は毎回新しいもの になるので,コンパイル結果を使い回しすることが出来ます(細かいことを言う と,グローバルに決まるコンパイルオプションを変えたときどうなるか,は違う のですが). -- // SASADA Koichi at atdot dot net