[#28653] create header (Re: Re: ossl_cipher.c:124: warning: control reaches end of non-void function) — "Nobuyoshi Nakada" <nobu@...>

なかだです。

8 messages 2006/05/18

[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);

In This Thread

Prev Next