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 »