summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSatoshi Tagomori <s-tagomori@sakura.ad.jp>2025-10-31 23:38:16 +0900
committerSatoshi Tagomori <tagomoris@gmail.com>2025-11-03 02:06:11 +0900
commite89eecceafea3f8834c6fc4cdd74a7812591cae5 (patch)
treeee8e872cf9ea3bd30c11b57ec0bbb71c52decd7a
parentbc77a11bd845e4c3d79b990c196fedca37e9ab0b (diff)
No need to call rb_define_class/module_under_id
Classes/modules defined in a namespace are defined under ::Object as usual (as without namespaces), and it'll be set into the const_tbl of ::Object. In namespaces, namespace objects' const_tbl is equal to the one of ::Object. So constants of ::Object are just equal to constants of the namespace. That means, top level classes/modules in a namespace can be referred as namespace::KlassName without calling rb_define_class_under_id().
-rw-r--r--class.c14
-rw-r--r--test/ruby/test_namespace.rb4
2 files changed, 6 insertions, 12 deletions
diff --git a/class.c b/class.c
index 5e50a281d9..a4249425a1 100644
--- a/class.c
+++ b/class.c
@@ -1605,13 +1605,8 @@ VALUE
rb_define_class(const char *name, VALUE super)
{
VALUE klass;
- ID id;
- const rb_namespace_t *ns = rb_current_namespace();
+ ID id = rb_intern(name);
- id = rb_intern(name);
- if (NAMESPACE_OPTIONAL_P(ns)) {
- return rb_define_class_id_under(ns->ns_object, id, super);
- }
if (rb_const_defined(rb_cObject, id)) {
klass = rb_const_get(rb_cObject, id);
if (!RB_TYPE_P(klass, T_CLASS)) {
@@ -1723,13 +1718,8 @@ VALUE
rb_define_module(const char *name)
{
VALUE module;
- ID id;
- const rb_namespace_t *ns = rb_current_namespace();
+ ID id = rb_intern(name);
- id = rb_intern(name);
- if (NAMESPACE_OPTIONAL_P(ns)) {
- return rb_define_module_id_under(ns->ns_object, id);
- }
if (rb_const_defined(rb_cObject, id)) {
module = rb_const_get(rb_cObject, id);
if (!RB_TYPE_P(module, T_MODULE)) {
diff --git a/test/ruby/test_namespace.rb b/test/ruby/test_namespace.rb
index af0d6173f2..2b7dd04ac7 100644
--- a/test/ruby/test_namespace.rb
+++ b/test/ruby/test_namespace.rb
@@ -715,6 +715,7 @@ class TestNamespace < Test::Unit::TestCase
def self.yield_block = yield
def self.call_block(&b) = b.call
end
+ FOO_NAME = Foo.name
NS9 = Foo.new.ns4
EOC
ns.eval(code)
@@ -731,6 +732,9 @@ class TestNamespace < Test::Unit::TestCase
assert_equal outer, ns::Foo.yield_block{ Namespace.current } # method yields
assert_equal outer, ns::Foo.call_block{ Namespace.current } # method calls a block
assert_equal ns, ns::NS9 # on TOP frame, referring a class in the current
+
+ assert_equal "Foo", ns::FOO_NAME
+ assert_equal "Foo", ns::Foo.name
end;
end