edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C444795
File: RubyTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;C444795  (server)    5/22/2008 3:26 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/RubyTests.cs;InstanceEval
@@ -313,17 +313,22 @@
                 Eval1,
                 Eval2,
                 LocalNames1,
+                LocalNames2,
+                // TODO: fix module scope to generate its own ScopeExpression LocalNames3,
                 Binding1,
                 TopLevelBinding_RubyProgram,
                 EvalWithProcBinding1,
                 ModuleEvalProc1,
                 ModuleEvalProc2,
                 ModuleEvalProc3,
+                ModuleInstanceEvalProc3,
                 ModuleClassNew1,
                 ModuleClassNew2,
                 ModuleEvalString1,
+                InstanceEvalString1,
                 ModuleEvalString2,
-                ModuleEvalString3,
+                InstanceEvalString2,
+                ModuleInstanceEvalString3,
 
                 SuperEval1,
                 // TODO: SuperParameterlessEval1,
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/EvalTests.cs;C438696
File: EvalTests.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/EvalTests.cs;C438696  (server)    5/22/2008 3:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/IronRuby.Tests/Runtime/EvalTests.cs;InstanceEval
@@ -70,7 +70,7 @@
                 CompilerTest(@"
 def f
   a = 1
-  puts local_variables
+  puts local_variables.sort
   b = 2
 end
 
@@ -81,6 +81,54 @@
 b");
         }
 
+        public void LocalNames2() {
+            AssertOutput(delegate() {
+                CompilerTest(@"
+def bar
+  1.times { |x|
+     y = 1
+     1.times { |z|
+       $b = binding
+     }
+  }
+end
+
+bar
+
+eval('puts local_variables.sort', $b)
+");
+            }, @"
+x
+y
+z
+");
+        }
+
+        public void LocalNames3() {
+            AssertOutput(delegate() {
+                CompilerTest(@"
+def bar
+  1.times { |x|
+     eval('module M
+       y = 1
+       1.times { |z|
+         $b = binding
+       }
+     end');
+  }
+end
+
+bar
+
+eval('puts local_variables.sort', $b)
+");
+            }, @"
+x
+y
+z
+");
+        }
+
         public void Binding1() {
             AssertOutput(delegate() {
                 CompilerTest(@"
@@ -177,6 +225,44 @@
 ");
         }
 
+        public void ModuleInstanceEvalProc3() {
+            AssertOutput(delegate() {
+                CompilerTest(@"
+class C
+  D = 1
+end
+
+C.module_eval {
+  p Module.nesting
+  puts D rescue puts 'error'
+  
+  def foo
+    puts 'foo'
+  end
+}
+
+C.instance_eval {
+  p Module.nesting
+  puts D rescue puts 'error'
+
+  def bar
+    puts 'bar'
+  end
+}
+
+C.new.foo
+C.bar
+");
+            }, @"
+[]
+error
+[]
+error
+foo
+bar
+");
+        }
+
         /// <summary>
         /// module_eval uses yield semantics for invoking the proc.
         /// (return in a yield to inactive lambda doesn't work).
@@ -251,7 +337,6 @@
 ");
         }
 
-
         public void ModuleEvalString1() {
             AssertOutput(delegate() {
                 CompilerTest(@"
@@ -268,6 +353,26 @@
 ");
         }
 
+        public void InstanceEvalString1() {
+            AssertOutput(delegate() {
+                CompilerTest(@"
+module N
+  module M
+    class << self
+      C = 123
+    end
+  end
+end
+
+N::M.instance_eval('p self, C, Module.nesting')
+");
+            }, @"
+N::M
+123
+[#<Class:N::M>]
+");
+        }
+
         public void ModuleEvalString2() {
             AssertOutput(delegate() {
                 CompilerTest(@"
@@ -280,9 +385,21 @@
             }, @"1");
         }
 
-        public void ModuleEvalString3() {
+        public void InstanceEvalString2() {
             AssertOutput(delegate() {
                 CompilerTest(@"
+class C
+end
+
+C.instance_eval('def foo; puts 1; end')
+C.foo
+");
+            }, @"1");
+        }
+
+        public void ModuleInstanceEvalString3() {
+            AssertOutput(delegate() {
+                CompilerTest(@"
 module M
 end
 
@@ -293,11 +410,14 @@
 def foo
   a = 1
   M.module_eval('puts a')
+  M.instance_eval('puts a')
 end
 
 foo
 ");
-            }, @"1");
+            }, @"
+1
+1");
         }
     }
 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C447029
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C447029  (server)    5/22/2008 4:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;InstanceEval
@@ -2293,6 +2293,7 @@
             });
             
             module.DefineLibraryMethod("instance_eval", 0x29, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, Ruby.Builtins.MutableString, Ruby.Builtins.MutableString, System.Int32, System.Object>(Ruby.Builtins.Kernel.Evaluate),
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, System.Object>(Ruby.Builtins.Kernel.InstanceEval),
             });
             
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C447029
File: Kernel.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;C447029  (server)    5/22/2008 2:58 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/Kernel.cs;InstanceEval
@@ -151,14 +151,14 @@
         [RubyMethod("eval", RubyMethodAttributes.PublicSingleton)]
         public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code, 
             [Optional]Binding binding, [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
-            return RubyUtils.Evaluate(self, code, (binding != null) ? binding.LocalScope : RubyUtils.GetScope(context), file, line);
+            return RubyUtils.Evaluate(code, (binding != null) ? binding.LocalScope : RubyUtils.GetScope(context), file, line);
         }
 
         [RubyMethod("eval", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("eval", RubyMethodAttributes.PublicSingleton)]
         public static object Evaluate(CodeContext/*!*/ context, object self, [NotNull]MutableString/*!*/ code,
             [NotNull]Proc/*!*/ procBinding, [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
-            return RubyUtils.Evaluate(self, code, procBinding.LocalScope, file, line);
+            return RubyUtils.Evaluate(code, procBinding.LocalScope, file, line);
         }
 
         //exec
@@ -715,29 +715,17 @@
         }
         #endregion
 
-#if TODO
-        static DynamicSite<BlockParam, object>/*!*/ _InstanceEvalSite = CallSiteFactory.CreateSimpleCallSite<BlockParam, object>(RubyContext.RubyBinder);
+        [RubyMethod("instance_eval")]
+        public static object Evaluate(CodeContext/*!*/ context, object self, BlockParam block, [NotNull]MutableString/*!*/ code,
+            [Optional, NotNull]MutableString file, [DefaultParameterValue(1)]int line) {
 
-        [RubyMethod("instance_eval")]
-        public static object InstanceEval(CodeContext/*!*/ context, object self, BlockParam block) {
-            if (block == null) {
-                throw RubyExceptions.CreateArgumentError("block not supplied");
+            // TODO: binder should do this:
+            if (block != null) {
+                throw RubyExceptions.CreateArgumentError("wrong number of arguments");
             }
-            // TODO: for modules/classes, this has different semantics. For example:
-            //   class Test; end
-            //   Test.instance_eval { def test_instance_eval; end }
-            //   Test.class_eval    { def test_class_eval; end }
-            //   p Test.instance_methods(false)  # => ["test_instance_eval"]
-            //   p Test.singleton_methods(false) # => ["test_class_eval"]
-            if (self is RubyModule) {
-                throw RubyExceptions.CreateNotImplementedError("instance_eval on Module or Class needs singleton support");
-            }
 
-            BlockParam newBlock = block.CloneWithNewSelf(self);
-            return _InstanceEvalSite.Invoke(context, newBlock);
-            throw new NotImplementedException("TODO");
+            return RubyUtils.Evaluate(code, RubyUtils.GetScope(context), self, null, file, line);
         }
-#endif
 
         private static DynamicSite<BlockParam/*!*/, object, object, object> _InstanceEvalSite =
             DynamicSite<BlockParam/*!*/, object, object, object>.Create(YieldAction.Make(RubyContext.RubyBinder, 2));
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C447029
File: ModuleOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;C447029  (server)    5/22/2008 4:09 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/ModuleOps.cs;InstanceEval
@@ -601,7 +601,7 @@
                 throw RubyExceptions.CreateArgumentError("wrong number of arguments");
             }
 
-            return RubyUtils.EvaluateInModule((RubyScope)context, self, code, file, line);
+            return RubyUtils.Evaluate(code, RubyUtils.GetScope(context), self, self, file, line);
         }
 
         [RubyMethod("module_eval")]
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Parser/LexicalScope.cs;C429806
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C447029
File: RubyOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C447029  (server)    5/22/2008 3:14 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;InstanceEval
@@ -114,14 +114,14 @@
         
         // emitted:
         public static CodeContext/*!*/ CreateEvalScope(ILocalVariables/*!*/ locals, CodeContext/*!*/ parent, bool isVisible) {
-            // TODO: hack, see module_eval
-            if (parent is ModuleEvalScope) {
-                ModuleEvalScope modEvalScope = (ModuleEvalScope)parent;
-                RubyScope callerScope = (RubyScope)modEvalScope.Parent;
+            // TODO: hack, see module_eval, instance_eval
+            EvalScopeHolder evalScope = parent as EvalScopeHolder;
+            if (evalScope != null) {
+                RubyScope callerScope = (RubyScope)evalScope.Parent;
 
-                RubyModuleScope result = new RubyModuleScope(callerScope, locals);
-                result.Initialize(callerScope.RuntimeFlowControl, callerScope.MethodAttributes, modEvalScope.SelfObject);
-                result.SetDebugName("top-module-eval");
+                RubyModuleScope result = new RubyModuleScope(callerScope, locals, evalScope.Module, true);
+                result.Initialize(callerScope.RuntimeFlowControl, callerScope.MethodAttributes, evalScope.SelfObject);
+                result.SetDebugName("top-module/instance-eval");
 
                 return result;
             } else {
@@ -153,7 +153,7 @@
         // emitted:
         public static CodeContext/*!*/ CreateModuleScope(ILocalVariables/*!*/ locals, CodeContext/*!*/ parent, bool isVisible) {
             RubyScope p = (RubyScope)parent;
-            return new RubyModuleScope(p, p.Frame);
+            return new RubyModuleScope(p, p.Frame, null, false);
         }
 
         // TODO: remove
@@ -166,6 +166,7 @@
             RubyScope parent = (RubyScope)scope.Parent;
 
             result.Initialize(rfc, RubyMethodAttributes.PublicInstance, module);
+            result.SetModule(module);
             result.SetDebugName((module.IsClass ? "class" : "module") + " " + SymbolTable.IdToString(module.Name));
 
             // TODO: flow from parent, we might want to remove the fields from block scope:
@@ -243,11 +244,7 @@
 
         // emitted:
         public static object GetLocalVariable(RubyScope/*!*/ scope, SymbolId name) {
-            object result;
-            while (!scope.Frame.TryGetValue(name, out result) && scope.Parent != null) {
-                scope = (RubyScope)scope.Parent;
-            }
-            return result;
+            return scope.ResolveLocalVariable(name);
         }
 
         // emitted:
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C443395
File: RubyScope.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;C443395  (server)    5/22/2008 3:12 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyScope.cs;InstanceEval
@@ -50,6 +50,7 @@
         private RubyMethodAttributes _methodAttributes;
 
         public abstract ScopeKind Kind { get; }
+        public abstract bool InheritsLocalVariables { get; }
 
         public virtual RubyModule Module {
             get { return null; }
@@ -176,14 +177,36 @@
         // TODO:
         public List<SymbolId>/*!*/ GetVisibleLocalNames() {
             List<SymbolId> result = new List<SymbolId>();
+            RubyScope scope = this;
+            while (true) {
+                foreach (string name in scope.LocalNames) {
+                    if (!name.StartsWith("#")) {
+                        result.Add(SymbolTable.StringToId(name));
+                    }
+                }
 
-            foreach (string name in LocalNames) {
-                if (!name.StartsWith("#")) {
-                    result.Add(SymbolTable.StringToId(name));
+                if (!scope.InheritsLocalVariables) {
+                    return result;
                 }
+
+                scope = (RubyScope)scope.Parent;
             }
+        }
 
-            return result;
+        internal object ResolveLocalVariable(SymbolId name) {
+            RubyScope scope = this;
+            while (true) {
+                object result;
+                if (scope.Frame.TryGetValue(name, out result)) {
+                    return result;
+                }
+
+                if (!scope.InheritsLocalVariables) {
+                    return null;
+                }
+
+                scope = (RubyScope)scope.Parent;
+            }
         }
 
         #region Debug View
@@ -217,7 +240,7 @@
                             }
                         }
 
-                        if (scope.Kind != ScopeKind.Block) {
+                        if (!scope.InheritsLocalVariables) {
                             break;
                         }
                         scope = (RubyScope)scope.Parent;
@@ -231,9 +254,10 @@
                 get { return _scope._selfObject; }
             }
 
+            [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
             [DebuggerDisplay("{A2 != null ? A2.ToString() : \"nil\",nq}", Name = "$~", Type = "{_matchClassName,nq}")]
             public Match A2 {
-                get { return _scope._currentMatch.Match; }
+                get { return (_scope._currentMatch != null) ? _scope._currentMatch.Match : null; }
             }
 
             [DebuggerDisplay("{B}", Name = "MethodAttributes", Type = "")]
@@ -283,6 +307,7 @@
         private Proc _blockParameter;
         
         public override ScopeKind Kind { get { return ScopeKind.Method; } }
+        public override bool InheritsLocalVariables { get { return false; } }
 
         public RubyMethodInfo Method {
             get { return _method; }
@@ -300,19 +325,27 @@
     }
 
     public sealed class RubyModuleScope : RubyScope {
+        // TODO: readonly
+        private RubyModule _module;
+        private readonly bool _isEval;
+
         public override ScopeKind Kind { get { return ScopeKind.Module; } }
+        public override bool InheritsLocalVariables { get { return _isEval; } }
 
-        public override RubyModule Module {
-            get { return (RubyModule)SelfObject; }
-        }
+        public override RubyModule Module { get { return _module; } }
 
-        internal RubyModuleScope(RubyScope/*!*/ parent, ILocalVariables/*!*/ frame)
+        internal void SetModule(RubyModule/*!*/ module) { _module = module; }
+
+        internal RubyModuleScope(RubyScope/*!*/ parent, ILocalVariables/*!*/ frame, RubyModule module, bool isEval)
             : base(parent, frame) {
+            _module = module;
+            _isEval = isEval;
         }
     }
 
     public sealed class RubyBlockScope : RubyScope {
         public override ScopeKind Kind { get { return ScopeKind.Block; } }
+        public override bool InheritsLocalVariables { get { return true; } }
 
         // TODO: readonly
         private BlockParam _blockParam;
@@ -329,6 +362,7 @@
 
     public sealed class RubyTopLevelScope : RubyScope {
         public override ScopeKind Kind { get { return ScopeKind.TopLevel; } }
+        public override bool InheritsLocalVariables { get { return false; } }
 
         private readonly bool _isMain;
         private readonly GlobalScopeExtension/*!*/ _globalScope;
@@ -395,15 +429,18 @@
 
     }
  
-    // TODO: remove (see module_eval)
-    public sealed class ModuleEvalScope : RubyScope {
-        public override ScopeKind Kind {
-            get { throw new NotImplementedException(); }
-        }
+    // TODO: remove (see module_eval, instance_eval)
+    public sealed class EvalScopeHolder : RubyScope {
+        private readonly RubyModule _module;
 
-        public ModuleEvalScope(RubyScope/*!*/ loader, RubyModule/*!*/ self)
+        public override ScopeKind Kind { get { throw new NotImplementedException(); } }
+        public override bool InheritsLocalVariables { get { throw new NotImplementedException(); } }
+        public override RubyModule Module { get { return _module; } }
+
+        public EvalScopeHolder(RubyScope/*!*/ loader, object self, RubyModule module)
             : base(loader, loader.Frame) {
             SelfObject = self;
+            _module = module;
         }
     }
 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C445425
File: RubyUtils.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;C445425  (server)    5/22/2008 3:02 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyUtils.cs;InstanceEval
@@ -493,7 +493,7 @@
             }
         }
 
-        public static object Evaluate(object self, MutableString/*!*/ code, RubyScope/*!*/ targetScope, MutableString file, int line) {
+        public static object Evaluate(MutableString/*!*/ code, RubyScope/*!*/ targetScope, MutableString file, int line) {
             Assert.NotNull(code, targetScope);
 
             RubyExecutionContext ec = targetScope.ExecutionContext;
@@ -511,22 +511,27 @@
             return compiledCode.Run(targetScope, false);
         }
 
-        public static object EvaluateInModule(RubyScope/*!*/ currentScope, RubyModule/*!*/ self, MutableString/*!*/ code, MutableString file, int line) {
+        public static object Evaluate(MutableString/*!*/ code, RubyScope/*!*/ targetScope, object self, RubyModule module, MutableString file, int line) {
             Assert.NotNull(self, code);
 
-            RubyExecutionContext ec = currentScope.ExecutionContext;
+            RubyExecutionContext ec = targetScope.ExecutionContext;
 
+            // singleton class for instance eval:
+            if (module == null) {
+                module = ec.CreateSingletonClass(self);
+            }
+
             // we want to create a new top-level local scope:
             RubyCompilerOptions options = new RubyCompilerOptions();
             options.IsEval = true;
-            options.LocalNames = currentScope.GetVisibleLocalNames();
+            options.LocalNames = targetScope.GetVisibleLocalNames();
 
             SourceUnit source = ec.Context.CreateSnippet(code.ConvertToString());
             ScriptCode compiledCode = source.Compile(options, ec.RuntimeErrorSink);
             Debug.Assert(compiledCode != null);
 
             // TODO: this is hack - we need arbitrary signature of the Initialize method:
-            ModuleEvalScope moduleEvalScope = new ModuleEvalScope(currentScope, self);
+            EvalScopeHolder moduleEvalScope = new EvalScopeHolder(targetScope, self, module);
 
             return compiledCode.Run(moduleEvalScope, false);
         }
===================================================================
delete: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Specs/core/kernel/.spec/instance_eval_excludes.txt;C422137
File: instance_eval_excludes.txt
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Tests/Specs/core/kernel/.spec/instance_eval_excludes.txt;C422137  (server)    5/22/2008 5:14 PM
+++ [no target file]
@@ -1,4 +1,0 @@
-Kernel#instance_eval passes the object to the block
-Kernel#instance_eval binds self to the receiver
-Kernel#instance_eval executes in the context of the receiver
-Kernel#instance_eval has access to receiver's instance variables
===================================================================
