Kernel also is one of modules.
···
===================================================================
RCS file: /cvs/ruby/src/ruby/object.c,v
retrieving revision 1.169
diff -U2 -p -r1.169 object.c
--- object.c 11 May 2005 07:00:32 -0000 1.169
+++ object.c 24 Jun 2005 04:37:33 -0000
@@ -1715,9 +1715,46 @@ rb_mod_attr_accessor(argc, argv, klass)
}
+static ID
+mod_const_id(namep)
+ volatile VALUE *namep;
+{
+ VALUE tmp, name = *namep;
+ ID id;
+
+ switch (TYPE(name)) {
+ case T_STRING:
+ break;
+ case T_FIXNUM:
+ rb_warn("do not use Fixnums as Symbols");
+ id = FIX2LONG(name);
+ if (!rb_id2name(id)) {
+ rb_raise(rb_eArgError, "%ld is not a symbol", id);
+ }
+ return id;
+ case T_SYMBOL:
+ return SYM2ID(name);
+ default:
+ tmp = rb_check_string_type(name);
+ if (NIL_P(tmp)) {
+ rb_raise(rb_eTypeError, "%s is not a symbol", RSTRING(rb_inspect(name))->ptr);
+ }
+ *namep = name = tmp;
+ }
+ if (RSTRING(name)->ptr && strchr(RSTRING(name)->ptr, ':'))
+ return 0;
+
+ id = str_to_id(name);
+ if (!rb_is_const_id(id)) {
+ rb_name_error(id, "wrong constant name %s", rb_id2name(id));
+ }
+
+ return id;
+}
+
/*
* call-seq:
* mod.const_get(sym) => obj
*
- * Returns the value of the named constant in <i>mod</i>.
+ * Returns the value of the named constant under <i>mod</i>.
*
* Math.const_get(:PI) #=> 3.14159265358979
@@ -1728,9 +1765,10 @@ rb_mod_const_get(mod, name)
VALUE mod, name;
{
- ID id = rb_to_id(name);
+ ID id = mod_const_id(&name);
- if (!rb_is_const_id(id)) {
- rb_name_error(id, "wrong constant name %s", rb_id2name(id));
+ if (!id) {
+ return rb_path2const(RSTRING(name)->ptr, mod, Qtrue);
}
+
return rb_const_get(mod, id);
}
Index: variable.c
RCS file: /cvs/ruby/src/ruby/variable.c,v
retrieving revision 1.121
diff -U2 -p -r1.121 variable.c
--- variable.c 13 May 2005 08:56:14 -0000 1.121
+++ variable.c 24 Jun 2005 04:17:48 -0000
@@ -234,11 +234,21 @@ rb_set_class_path(klass, under, name)
VALUE
-rb_path2class(path)
+rb_path2const(path, cbase, idcheck)
const char *path;
+ VALUE cbase;
+ int idcheck;
{
const char *pbeg, *p;
ID id;
- VALUE c = rb_cObject;
+ VALUE c = cbase;
+ switch (TYPE(cbase)) {
+ case T_MODULE:
+ case T_CLASS:
+ break;
+ default:
+ rb_raise(rb_eTypeError, "class or module required but %s given",
+ rb_obj_classname(cbase));
+ }
if (path[0] == '#') {
rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path);
@@ -249,6 +259,9 @@ rb_path2class(path)
while (*p && *p != ':') p++;
- str = rb_str_new(pbeg, p-pbeg);
+ *(volatile VALUE *)&str = rb_str_new(pbeg, p-pbeg);
id = rb_intern(RSTRING(str)->ptr);
+ if (idcheck && !rb_is_const_id(id)) {
+ rb_name_error(id, "wrong constant name %s", RSTRING(str)->ptr);
+ }
if (p[0] == ':') {
if (p[1] != ':') goto undefined_class;
@@ -258,7 +271,15 @@ rb_path2class(path)
if (!rb_const_defined(c, id)) {
undefined_class:
- rb_raise(rb_eArgError, "undefined class/module %.*s", p-path, path);
+ if (cbase == rb_cObject) {
+ rb_raise(rb_eArgError, "undefined class/module %s",
+ RSTRING(str)->ptr);
+ }
+ else {
+ rb_raise(rb_eArgError, "undefined class/module %s under %s",
+ RSTRING(str)->ptr, rb_class2name(c));
+ }
}
c = rb_const_get_at(c, id);
+ if (!*p) break;
switch (TYPE(c)) {
case T_MODULE:
@@ -273,4 +294,21 @@ rb_path2class(path)
}
+VALUE
+rb_path2class(path)
+ const char *path;
+{
+ VALUE c = rb_path2const(path, rb_cObject, Qfalse);
+
+ switch (TYPE(c)) {
+ case T_MODULE:
+ case T_CLASS:
+ break;
+ default:
+ rb_raise(rb_eTypeError, "%s does not refer class/module", path);
+ }
+
+ return c;
+}
+
void
rb_name_class(klass, id)
Index: intern.h
RCS file: /cvs/ruby/src/ruby/intern.h,v
retrieving revision 1.170
diff -U2 -p -r1.170 intern.h
--- intern.h 12 Jun 2005 16:56:05 -0000 1.170
+++ intern.h 24 Jun 2005 03:57:26 -0000
@@ -504,6 +504,7 @@
VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE));
void rb_set_class_path _((VALUE, VALUE, const char*));
+VALUE rb_path2const _((const char*, VALUE, int));
VALUE rb_path2class _((const char*));
void rb_name_class _((VALUE, ID));
VALUE rb_class_name _((VALUE));
--
Nobu Nakada