[ruby-dev:28633] load_to(file, mod)
From:
Hidetoshi NAGAI <nagai@...>
Date:
2006-05-11 16:03:32 UTC
List:
ruby-dev #28633
永井@知能.九工大です.
指定したモジュール下に 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 <code>load</code> function).
+ * If the filename does not
+ * resolve to an absolute path, the file is searched for in the library
+ * directories listed in <code>$:</code>.
+ */
+
+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);