From: Hidetoshi NAGAI Date: 2006-05-12T01:03:32+09:00 Subject: [ruby-dev:28633] load_to(file, mod) 永井@知能.九工大です. 指定したモジュール下に load するために subject に示したような 関数型のメソッドが (名前の良し悪しは保留として) 欲しいなと思っています. # load(file, true) は load_to(file, Module.new) と同じです. そういうものがないように見えるのは,実は (1) 適切な方法が他に存在する (2) Thread との絡みで落ちる or 正常に動かない危険性があるため (3) 何らかのセキュリティホールとなりうるため (4) そもそもそんなものが欲しいと思う発想自体がおかしい (5) その他,特別な理由が存在する のいずれかまたは複数が成立しているのに 単に私が気が付いていないだけなのでしょうか? # ちょっと調べた限りは見つけることができなかったのですが, # それも単に調べ方が足りないだけなのでしょうか?(^_^; 念のため,パッチを添えておきます. 引数が少し気持ち悪いですが,従来との互換性維持と 同じコードの繰り返し回避とのため ( + 手抜きのため ) に そうしてます. -- 永井 秀利 (九工大 知能情報) nagai@ai.kyutech.ac.jp Index: eval.c =================================================================== RCS file: /var/cvs/src/ruby/eval.c,v retrieving revision 1.890 diff -u -r1.890 eval.c --- eval.c 23 Feb 2006 04:24:39 -0000 1.890 +++ eval.c 11 May 2006 15:56:35 -0000 @@ -6618,7 +6618,7 @@ NORETURN(static void load_failed(VALUE)); void -rb_load(VALUE fname, int wrap) +rb_load_to(VALUE fname, int wrap, VALUE wrapper_mod) { VALUE tmp; int state; @@ -6647,8 +6647,14 @@ ruby_wrapper = 0; } else { - /* load in anonymous module as toplevel */ - ruby_wrapper = rb_module_new(); + if (rb_obj_is_kind_of(wrapper_mod, rb_cModule)) { + /* load in the module as toplevel */ + ruby_wrapper = wrapper_mod; + } + else { + /* load in anonymous module as toplevel */ + ruby_wrapper = rb_module_new(); + } self = rb_obj_clone(ruby_top_self); rb_extend_object(self, ruby_wrapper); PUSH_CREF(ruby_wrapper); @@ -6712,6 +6718,12 @@ } void +rb_load(VALUE fname, int wrap) +{ + rb_load_to(fname, wrap, Qnil); +} + +void rb_load_protect(VALUE fname, int wrap, int *state) { int status; @@ -6727,6 +6739,22 @@ if (state) *state = status; } +void +rb_load_protect_to(VALUE fname, int wrap, VALUE wrapper_mod, int *state) +{ + int status; + + PUSH_THREAD_TAG(); + if ((status = EXEC_TAG()) == 0) { + rb_load_to(fname, wrap, wrapper_mod); + } + else if (status == TAG_THREAD) { + rb_thread_start_1(); + } + POP_THREAD_TAG(); + if (state) *state = status; +} + /* * call-seq: * load(filename, wrap=false) => true @@ -6752,6 +6780,26 @@ return Qtrue; } + +/* + * call-seq: + * load_to(filename, wrapper) => true + * + * Loads and executes the Ruby + * program in the file _filename_ under the specified module _wrapper_ + * (See also the _wrap_ parameter of load function). + * If the filename does not + * resolve to an absolute path, the file is searched for in the library + * directories listed in $:. + */ + +static VALUE +rb_f_load_to(VALUE obj, VALUE fname, VALUE wrapper_mod) +{ + rb_load_to(fname, 1, wrapper_mod); + return Qtrue; +} + VALUE ruby_dln_librefs; static VALUE rb_features; static st_table *loading_tbl; @@ -7875,6 +7923,7 @@ rb_features = rb_ary_new(); rb_define_global_function("load", rb_f_load, -1); + rb_define_global_function("load_to", rb_f_load_to, 2); rb_define_global_function("require", rb_f_require, 1); rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2); rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);