Feature #5690 » p2c.diff
object.c | ||
---|---|---|
return Qnil;
|
||
}
|
||
static VALUE
|
||
rb_mod_single_const_get(VALUE mod, VALUE name, VALUE recur)
|
||
{
|
||
ID id;
|
||
id = rb_check_id(&name);
|
||
if (!id) {
|
||
if (!rb_is_const_name(name)) {
|
||
rb_name_error_str(name, "wrong constant name %s", RSTRING_PTR(name));
|
||
}
|
||
else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) {
|
||
id = rb_to_id(name);
|
||
}
|
||
else if (mod && rb_class_real(mod) != rb_cObject) {
|
||
rb_name_error_str(name, "uninitialized constant %s::%s",
|
||
rb_class2name(mod),
|
||
RSTRING_PTR(name));
|
||
}
|
||
else {
|
||
rb_name_error_str(name, "uninitialized constant %s", RSTRING_PTR(name));
|
||
}
|
||
}
|
||
if (!rb_is_const_id(id)) {
|
||
rb_name_error(id, "wrong constant name %s", rb_id2name(id));
|
||
}
|
||
return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
|
||
}
|
||
/*
|
||
* call-seq:
|
||
* mod.const_get(sym, inherit=true) -> obj
|
||
* mod.const_get(str, inherit=true) -> obj
|
||
*
|
||
* Checks for a constant with the given name in <i>mod</i>
|
||
* If +inherit+ is set, the lookup will also search
|
||
... | ... | |
* otherwise a +NameError+ is raised.
|
||
*
|
||
* Math.const_get(:PI) #=> 3.14159265358979
|
||
*
|
||
* This method will recursively look up constant names if a namespaced
|
||
* class name is provided. For example:
|
||
*
|
||
* module Foo; class Bar; end end
|
||
* Object.const_get 'Foo::Bar'
|
||
*
|
||
* The +inherit+ flag is respected on each lookup. For example:
|
||
*
|
||
* module Foo
|
||
* class Bar
|
||
* VAL = 10
|
||
* end
|
||
*
|
||
* class Baz < Bar; end
|
||
* end
|
||
*
|
||
* Object.const_get 'Foo::Baz::VAL' # => 10
|
||
* Object.const_get 'Foo::Baz::VAL', false # => NameError
|
||
*/
|
||
static VALUE
|
||
rb_mod_const_get(int argc, VALUE *argv, VALUE mod)
|
||
{
|
||
VALUE name, recur;
|
||
rb_encoding *enc;
|
||
const char *pbeg, *p, *path;
|
||
ID id;
|
||
if (argc == 1) {
|
||
... | ... | |
else {
|
||
rb_scan_args(argc, argv, "11", &name, &recur);
|
||
}
|
||
id = rb_check_id(&name);
|
||
if (!id) {
|
||
if (!rb_is_const_name(name)) {
|
||
rb_name_error_str(name, "wrong constant name %s", RSTRING_PTR(name));
|
||
}
|
||
else if (!rb_method_basic_definition_p(CLASS_OF(mod), id_const_missing)) {
|
||
id = rb_to_id(name);
|
||
}
|
||
else if (mod && rb_class_real(mod) != rb_cObject) {
|
||
rb_name_error_str(name, "uninitialized constant %s::%s",
|
||
rb_class2name(mod),
|
||
RSTRING_PTR(name));
|
||
if (SYMBOL_P(name)) {
|
||
name = rb_sym_to_s(name);
|
||
}
|
||
enc = rb_enc_get(name);
|
||
path = RSTRING_PTR(name);
|
||
if (!rb_enc_asciicompat(enc)) {
|
||
rb_raise(rb_eArgError, "invalid class path encoding (non ASCII)");
|
||
}
|
||
pbeg = p = path;
|
||
while (*p) {
|
||
while (*p && *p != ':') p++;
|
||
id = rb_intern3(pbeg, p-pbeg, enc);
|
||
if (p[0] == ':') {
|
||
if (p[1] != ':') {
|
||
rb_raise(rb_eArgError, "undefined class/module %.*s", (int)(p-path), path);
|
||
}
|
||
p += 2;
|
||
pbeg = p;
|
||
}
|
||
else {
|
||
rb_name_error_str(name, "uninitialized constant %s", RSTRING_PTR(name));
|
||
if (!RB_TYPE_P(mod, T_MODULE) && !RB_TYPE_P(mod, T_CLASS)) {
|
||
rb_raise(rb_eTypeError, "%s does not refer to class/module", path);
|
||
}
|
||
mod = rb_mod_single_const_get(mod, ID2SYM(id), recur);
|
||
}
|
||
if (!rb_is_const_id(id)) {
|
||
rb_name_error(id, "wrong constant name %s", rb_id2name(id));
|
||
}
|
||
return RTEST(recur) ? rb_const_get(mod, id) : rb_const_get_at(mod, id);
|
||
return mod;
|
||
}
|
||
/*
|
test/ruby/test_module.rb | ||
---|---|---|
assert_equal(Math::PI, Math.const_get(:PI))
|
||
end
|
||
def test_nested_get
|
||
assert_equal Other, Object.const_get([self.class, Other].join('::'))
|
||
assert_equal User::USER, self.class.const_get([User, 'USER'].join('::'))
|
||
end
|
||
def test_nested_get_symbol
|
||
const = [self.class, Other].join('::').to_sym
|
||
assert_equal Other, Object.const_get(const)
|
||
assert_equal User::USER, self.class.const_get([User, 'USER'].join('::'))
|
||
end
|
||
def test_nested_get_const_missing
|
||
classes = []
|
||
klass = Class.new {
|
||
define_singleton_method(:const_missing) { |name|
|
||
classes << name
|
||
klass
|
||
}
|
||
}
|
||
klass.const_get("Foo::Bar::Baz")
|
||
assert_equal [:Foo, :Bar, :Baz], classes
|
||
end
|
||
def test_nested_bad_class
|
||
assert_raises(TypeError) do
|
||
self.class.const_get([User, 'USER', 'Foo'].join('::'))
|
||
end
|
||
end
|
||
def test_const_set
|
||
assert(!Other.const_defined?(:KOALA))
|
||
Other.const_set(:KOALA, 99)
|
- « Previous
- 1
- 2
- 3
- 4
- Next »