<?xml version="1.0" encoding="UTF-8"?>
<commit>
  <added type="array">
    <added>
      <filename>doc/cref_vs_class.txt</filename>
    </added>
  </added>
  <modified type="array">
    <modified>
      <diff>@@ -59,6 +59,11 @@ class StaticScope
   # Static scope object this scope enclosed into.
   attr_reader   :parent
 
+  # Module or class representing the 'current class'. MRI manipulates
+  # this outside of the lexical scope and uses it for undef and method
+  # definition.
+  attr_accessor :current_module
+
   def inspect
     &quot;#&lt;#{self.class.name}:0x#{self.object_id.to_s(16)} parent=#{@parent.inspect} module=#{@module}&gt;&quot;
   end
@@ -66,6 +71,19 @@ class StaticScope
   def to_s
     self.inspect
   end
+
+  # Use the same info as the current StaticScope, but set current_module to
+  # +mod+. Chains off the current StaticScope.
+  def using_current_as(mod)
+    ss = StaticScope.new @module, self
+    ss.current_module = mod
+    return ss
+  end
+
+  def for_method_definition
+    return @current_module if @current_module
+    return @module
+  end
 end
 
 class CompiledMethod &lt; Executable</diff>
      <filename>kernel/common/compiled_method.rb</filename>
    </modified>
    <modified>
      <diff>@@ -106,7 +106,7 @@ module Kernel
       end
       # Return a copy of the BlockEnvironment with the receiver set to self
       env = prc.block.redirect_to self
-      env.method.scope = StaticScope.new(__metaclass__, env.method.scope)
+      env.method.scope = env.method.scope.using_current_as(__metaclass__)
       original_scope = prc.block.home.method.scope
       env.constant_scope = original_scope
       return env.call(*self)
@@ -128,7 +128,7 @@ module Kernel
         compiled_method.scope = StaticScope.new(self, compiled_method.scope)
       else
 
-      # Otherwise add our metaclass, so thats where new methods go.
+        # Otherwise add our metaclass, so thats where new methods go.
         compiled_method.scope = StaticScope.new(metaclass, compiled_method.scope)
       end
       compiled_method.compile</diff>
      <filename>kernel/common/eval.rb</filename>
    </modified>
    <modified>
      <diff>@@ -328,8 +328,7 @@ class MethodContext
   # Called when 'def name' is used in userland
 
   def __add_method__(name, obj)
-    s = MethodContext.current.sender
-    scope = s.method_scope || :public
+    scope = method_scope || :public
 
     if name == :initialize or scope == :module or name == :initialize_copy
       visibility = :private
@@ -341,26 +340,33 @@ class MethodContext
     obj.serial = 1
 
     # Push the scoping down.
-    obj.scope = s.method.scope
+    obj.scope = method.scope
 
     Rubinius::VM.reset_method_cache(name)
 
     cm_vis = CompiledMethod::Visibility.new(obj, visibility)
 
-    obj.scope.module.method_table[name] = cm_vis
+    mod = obj.scope.for_method_definition
+
+    mod.method_table[name] = cm_vis
 
     if scope == :module
-      s.current_scope.module_function name
+      mod.module_function name
     end
 
-    if s.current_scope.respond_to? :method_added
-      s.current_scope.method_added(name)
+    if mod.respond_to? :method_added
+      mod.method_added name
     end
 
     # Return value here is the return value of the 'def' expression
     return obj
   end
 
+  def __undef_method__(name)
+    mod = method.scope.for_method_definition
+    mod.undef_method name
+  end
+
   attr_reader :dynamic_locals
 
   ##</diff>
      <filename>kernel/common/method_context.rb</filename>
    </modified>
    <modified>
      <diff>@@ -2391,12 +2391,9 @@ class Compiler
 
     class Undef
       def bytecode(g)
-        g.push :self
-        unless @in_module
-          g.send :metaclass, 0
-        end
+        g.push_context
         g.push_literal @name
-        g.send :undef_method, 1
+        g.send :__undef_method__, 1
       end
     end
 </diff>
      <filename>lib/compiler/bytecode.rb</filename>
    </modified>
    <modified>
      <diff>@@ -620,11 +620,10 @@ class TestGenerator
   def undef_bytecode(*names)
     last_name = names.last
     names.each do |name|
-      self.push :self
-      self.send :metaclass, 0
-      self.push_literal name
-      self.send :undef_method, 1
-      self.pop unless name == last_name
+      push_context
+      push_literal name
+      send :__undef_method__, 1
+      pop unless name == last_name
     end
   end
 end</diff>
      <filename>spec/custom/helpers/generator.rb</filename>
    </modified>
    <modified>
      <diff>@@ -12,4 +12,12 @@ namespace rubinius {
   StaticScope* StaticScope::create(STATE) {
     return state-&gt;new_object&lt;StaticScope&gt;(G(staticscope));
   }
+
+  Module* StaticScope::for_method_definition() {
+    if(current_module_-&gt;nil_p()) {
+      return module_;
+    }
+
+    return current_module_;
+  }
 }</diff>
      <filename>vm/builtin/staticscope.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -14,12 +14,19 @@ namespace rubinius {
 
   private:
     Module* module_;      // slot
+
+    // This is used like the ruby_class MRI variable. It lets
+    // manipulate this aspect of the class lexical enclosure
+    // without having to change module also.
+    Module* current_module_;   // slot
+
     StaticScope* parent_; // slot
 
   public:
     /* accessors */
 
     attr_accessor(module, Module);
+    attr_accessor(current_module, Module);
     attr_accessor(parent, StaticScope);
 
     /* interface */
@@ -27,6 +34,9 @@ namespace rubinius {
     static void init(STATE);
     static StaticScope* create(STATE);
 
+    // The module to use when adding and removing methods
+    Module* for_method_definition();
+
     class Info : public TypeInfo {
     public:
       BASIC_TYPEINFO(TypeInfo)</diff>
      <filename>vm/builtin/staticscope.hpp</filename>
    </modified>
    <modified>
      <diff>@@ -350,11 +350,11 @@ namespace rubinius {
 
     cur = active_-&gt;cm()-&gt;scope();
     while(!cur-&gt;nil_p()) {
+      if(cur-&gt;module() == G(object)) break;
+
       result = cur-&gt;module()-&gt;get_const_association(state, name, found);
       if(*found) return result;
 
-      if(cur-&gt;module() == G(object)) break;
-
       cur = cur-&gt;parent();
     }
 </diff>
      <filename>vm/builtin/task.cpp</filename>
    </modified>
    <modified>
      <diff>@@ -117,7 +117,7 @@ class Instructions
   end
 
   # [Operation]
-  #   Set the StaticScope of the current CompiledMethod
+  #   Add a new StaticScope entry for the given Module
   # [Format]
   #   \push_scope
   # [Stack Before]
@@ -126,10 +126,11 @@ class Instructions
   # [Stack After]
   #   * ...
   # [Description]
-  #   Create a new StaticScope object and set it to the current
-  #   CompiledMethod object. The value on the top of the stack is set
-  #   to be the module within the StaticScope. This scope is chained off
-  #   the current scope of the method.
+  #   Create a new StaticScope object for the given Module on the stack.
+  #   This scope is chained off the current scope of the method.
+  #
+  #   This also sets the scope of the current CompiledMethod to the new
+  #   StaticScope
   #
 
   def add_scope</diff>
      <filename>vm/instructions.rb</filename>
    </modified>
  </modified>
  <removed type="array"/>
  <parents type="array">
    <parent>
      <id>77136ef9cd8ad10d61acb55cf96296b648d869b0</id>
    </parent>
  </parents>
  <author>
    <name>Evan Phoenix</name>
    <email>ephoenix@engineyard.com</email>
  </author>
  <url>http://github.com/evanphx/rubinius/commit/34efedf95ebe0cf875d9db3797db5bd69c95e4e3</url>
  <id>34efedf95ebe0cf875d9db3797db5bd69c95e4e3</id>
  <committed-date>2009-01-25T00:30:02-08:00</committed-date>
  <authored-date>2009-01-25T00:29:33-08:00</authored-date>
  <message>Fix some scoping usage and constant lookup</message>
  <tree>bab12fbe04e219d4d661a365c4960541e8e0efeb</tree>
  <committer>
    <name>Evan Phoenix</name>
    <email>ephoenix@engineyard.com</email>
  </committer>
</commit>
