summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-29 00:11:11 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2003-05-29 00:11:11 +0000
commit5ddce4f7bccc47a3c73860622f55f40c987ce592 (patch)
tree9847c8a5146f876cb72e94991ceeece3e3b9e92c /eval.c
parent144caca6bbc27ce2d2c681e381ffb912189c73b1 (diff)
* eval.c (ev_const_defined, ev_const_get), variable.c
(rb_const_get_at, rb_const_get, rb_mod_remove_const): use Qundef as autoload marker. [ruby-dev:18103], [ruby-dev:18184] * eval.c (rb_mod_autoload, rb_mod_autoload_p): new method; Module#autoload, Module#autoload?. * variable.c (rb_autoload, rb_autoload_load, rb_autoload_p): manage autoload constants per classes/modules. * variable.c (rb_const_defined_at, rb_const_defined): return false for autoloading constants. * class.c (rb_define_class, rb_define_module), eval.c (rb_eval), variable.c (rb_mod_const_at, rb_const_assign): removed autoload stuff. * intern.h: prototypes; rb_autoload, rb_autoload_load, rb_autoload_p. * lib/optparse.rb (OptionParser::Switch::PlacedArgument::parse): do not treat unmatched argument as an option. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3874 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c61
1 files changed, 51 insertions, 10 deletions
diff --git a/eval.c b/eval.c
index d37ace4b65..c858490496 100644
--- a/eval.c
+++ b/eval.c
@@ -1648,12 +1648,16 @@ ev_const_defined(cref, id, self)
VALUE self;
{
NODE *cbase = cref;
+ VALUE result;
while (cbase && cbase->nd_next) {
struct RClass *klass = RCLASS(cbase->nd_clss);
if (NIL_P(klass)) return rb_const_defined(CLASS_OF(self), id);
- if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) {
+ if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, &result)) {
+ if (result == Qundef && NIL_P(rb_autoload_p((VALUE)klass, id))) {
+ return Qfalse;
+ }
return Qtrue;
}
cbase = cbase->nd_next;
@@ -1674,7 +1678,11 @@ ev_const_get(cref, id, self)
VALUE klass = cbase->nd_clss;
if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id);
- if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
+ while (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
+ if (result == Qundef) {
+ rb_autoload_load(klass, id);
+ continue;
+ }
return result;
}
cbase = cbase->nd_next;
@@ -3502,9 +3510,6 @@ rb_eval(self, n)
cbase = class_prefix(self, node->nd_cpath);
cname = node->nd_cpath->nd_mid;
- if ((cbase == rb_cObject) && rb_autoload_defined(cname)) {
- rb_autoload_load(cname);
- }
if (rb_const_defined_at(cbase, cname)) {
klass = rb_const_get(cbase, cname);
if (TYPE(klass) != T_CLASS) {
@@ -3548,9 +3553,6 @@ rb_eval(self, n)
}
cbase = class_prefix(self, node->nd_cpath);
cname = node->nd_cpath->nd_mid;
- if ((cbase == rb_cObject) && rb_autoload_defined(cname)) {
- rb_autoload_load(cname);
- }
if (rb_const_defined_at(cbase, cname)) {
module = rb_const_get(cbase, cname);
if (TYPE(module) != T_MODULE) {
@@ -6512,7 +6514,43 @@ Init_eval()
rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
}
-VALUE rb_f_autoload();
+static VALUE
+rb_mod_autoload(mod, sym, file)
+ VALUE mod;
+ VALUE sym;
+ VALUE file;
+{
+ ID id = rb_to_id(sym);
+
+ Check_SafeStr(file);
+ rb_autoload(mod, id, RSTRING(file)->ptr);
+ return Qnil;
+}
+
+static VALUE
+rb_mod_autoload_p(mod, sym)
+ VALUE mod, sym;
+{
+ return rb_autoload_p(mod, rb_to_id(sym));
+}
+
+static VALUE
+rb_f_autoload(obj, sym, file)
+ VALUE obj;
+ VALUE sym;
+ VALUE file;
+{
+ return rb_mod_autoload(ruby_class, sym, file);
+}
+
+static VALUE
+rb_f_autoload_p(obj, sym)
+ VALUE obj;
+ VALUE sym;
+{
+ /* use ruby_class as same as rb_f_autoload. */
+ return rb_mod_autoload_p(ruby_class, sym);
+}
void
Init_load()
@@ -6527,7 +6565,10 @@ Init_load()
rb_define_global_function("load", rb_f_load, -1);
rb_define_global_function("require", rb_f_require, 1);
- rb_define_global_function("autoload", rb_f_autoload, 2);
+ rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
+ rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
+ rb_define_global_function("autoload", rb_f_autoload, 2);
+ rb_define_global_function("autoload?", rb_f_autoload_p, 1);
rb_global_variable(&ruby_wrapper);
ruby_dln_librefs = rb_ary_new();