From a2ec8666cf8fbb579fa48c73bd114908dbbc4a85 Mon Sep 17 00:00:00 2001
From: mame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>
Date: Fri, 28 Jan 2011 17:57:34 +0000
Subject: * compile.c (NODE_CLASS, NODE_MODULE), insns.def (defineclass): raise
   an exception when "class Foo::Bar" is evaluated and Foo::Bar is   private. 
 To implement this, define_type of "defineclass" is added   so that the
 instruction can distinguish whether the class definition   is scoped (class
 Foo::Bar) or not (class Bar).

* test/ruby/test_class.rb (test_redefine_private_class),
  test/ruby/test_module.rb
  (test_define_module_under_private_constant): add tests for above.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@30714 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
---
 insns.def | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

(limited to 'insns.def')

diff --git a/insns.def b/insns.def
index e45609b880..72b0f27cc6 100644
--- a/insns.def
+++ b/insns.def
@@ -894,7 +894,8 @@ defineclass
     VALUE klass;
 
     switch ((int)define_type) {
-      case 0:
+      case 0: /* scoped:   class Foo::Bar */
+      case 3: /* no scope: class Bar */
 	/* val is dummy.  classdef returns class scope value */
 
 	if (super == Qnil) {
@@ -907,7 +908,7 @@ defineclass
 	rb_autoload_load(cbase, id);
 	if (rb_const_defined_at(cbase, id)) {
 	    /* already exist */
-	    klass = rb_const_get_at(cbase, id);
+	    klass = define_type == 0 ? rb_public_const_get(cbase, id) : rb_const_get_at(cbase, id);
 	    if (TYPE(klass) != T_CLASS) {
 		rb_raise(rb_eTypeError, "%s is not a class", rb_id2name(id));
 	    }
@@ -935,7 +936,8 @@ defineclass
 	/* super is dummy */
 	klass = rb_singleton_class(cbase);
 	break;
-      case 2:
+      case 2: /* scoped:   module Foo::Bar  or  module ::Bar */
+      case 5: /* no scope: module Bar */
 	/* val is dummy.  classdef returns class scope value */
 	/* super is dummy */
 
@@ -943,7 +945,7 @@ defineclass
 
 	/* find klass */
 	if (rb_const_defined_at(cbase, id)) {
-	    klass = rb_const_get_at(cbase, id);
+	    klass = define_type == 2 ? rb_public_const_get(cbase, id) : rb_const_get_at(cbase, id);
 	    /* already exist */
 	    if (TYPE(klass) != T_MODULE) {
 		rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(id));
-- 
cgit v1.2.3

