add: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/Methods/trace.rb
File: trace.rb
===================================================================
--- [no source file]
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Experimental/Methods/trace.rb;Trace
@@ -1,0 +1,52 @@
+def foo b, a = b+1
+  
+  
+  return 1
+  
+  
+end
+
+alias :bar :foo
+
+module M
+  def m
+  end
+end
+
+class C
+  include M
+  
+  def c  
+  end
+  
+  def C.s
+  end  
+  
+end
+
+x = C.new
+
+class << x
+  def z
+  end
+  $sx = self
+end
+
+p x
+
+def a
+end
+
+set_trace_func(proc { |*args|
+  if args[0] == "call"
+    p args 
+    p args[5].class
+    eval('puts a', args[4])
+  end
+})
+
+bar 1
+x.c
+x.m
+C.s
+x.z
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C450622
File: Initializers.Generated.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;C450622  (server)    5/28/2008 2:17 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Initializers.Generated.cs;Trace
@@ -2459,6 +2459,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Runtime.BlockParam, System.Object, System.Object[], System.Object>(Ruby.Builtins.KernelOps.SendMessage),
             });
             
+            module.DefineLibraryMethod("set_trace_func", 0x2a, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.Proc, Ruby.Builtins.Proc>(Ruby.Builtins.KernelOps.SetTraceListener),
+            });
+            
             module.DefineLibraryMethod("singleton_method_added", 0x2a, new System.Delegate[] {
                 new Microsoft.Scripting.Utils.Action<System.Object, System.Object>(Ruby.Builtins.KernelOps.MethodAdded),
             });
@@ -2665,6 +2669,10 @@
                 new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.RubyArray, Ruby.Builtins.RubyArray, Ruby.Builtins.RubyArray, System.Double, Ruby.Builtins.RubyArray>(Ruby.Builtins.KernelOps.Select),
             });
             
+            module.DefineLibraryMethod("set_trace_func", 0x31, new System.Delegate[] {
+                new Microsoft.Scripting.Utils.Function<Microsoft.Scripting.Runtime.CodeContext, System.Object, Ruby.Builtins.Proc, Ruby.Builtins.Proc>(Ruby.Builtins.KernelOps.SetTraceListener),
+            });
+            
             module.DefineLibraryMethod("sleep", 0x31, new System.Delegate[] {
                 new System.Action<System.Object>(Ruby.Builtins.KernelOps.Sleep),
                 new Microsoft.Scripting.Utils.Function<System.Object, System.Int32, System.Int32>(Ruby.Builtins.KernelOps.Sleep),
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C450567
File: KernelOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;C450567  (server)    5/28/2008 1:49 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Libraries.LCA_RESTRICTED/Builtins/KernelOps.cs;Trace
@@ -574,7 +574,15 @@
             return RubyIOOps.Select(context, null, read, write, error, timeoutInSeconds);
         }
 
-        //set_trace_func
+        [RubyMethod("set_trace_func", RubyMethodAttributes.PrivateInstance)]
+        [RubyMethod("set_trace_func", RubyMethodAttributes.PublicSingleton)]
+        public static Proc SetTraceListener(CodeContext/*!*/ context, object self, Proc listener) {
+            RubyExecutionContext ec = RubyUtils.GetExecutionContext(context);
+            if (!ec.Context.EngineOptions.EnableTracing) {
+                throw new NotSupportedException("Tracing is not supported unless -trace option is specified.");
+            }
+            return ec.TraceListener = listener;
+        }
 
         [RubyMethod("sleep", RubyMethodAttributes.PrivateInstance)]
         [RubyMethod("sleep", RubyMethodAttributes.PublicSingleton)]
@@ -889,9 +897,6 @@
         private static DynamicSite<BlockParam/*!*/, object, object, object> _InstanceEvalSite =
             DynamicSite<BlockParam/*!*/, object, object, object>.Create(YieldAction.Make(RubyContext.RubyBinder, 2));
 
-        // TODO: string
-        // TODO: method defs -> singletons, self == module?
-        // probably use module_function
         [RubyMethod("instance_eval")]
         public static object InstanceEval(CodeContext/*!*/ context, object self, BlockParam/*!*/ block) {
             if (block == null) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;C448766
File: AstGenerator.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;C448766  (server)    5/28/2008 1:25 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/AstGenerator.cs;Trace
@@ -41,13 +41,15 @@
         private readonly SourceUnit/*!*/ _sourceUnit;
         private readonly bool _debugCompiler;
         private readonly bool _debugMode;
+        private readonly bool _traceEnabled;
 
-        internal AstGenerator(CompilerContext/*!*/ compilerContext, bool debugCompiler, bool debugMode) {
+        internal AstGenerator(CompilerContext/*!*/ compilerContext, bool debugCompiler, bool debugMode, bool traceEnabled) {
             Assert.NotNull(compilerContext);
             _binder = compilerContext.SourceUnit.LanguageContext.Binder;
             _compilerOptions = (RubyCompilerOptions)compilerContext.Options;
             _debugCompiler = debugCompiler;
             _debugMode = debugMode;
+            _traceEnabled = traceEnabled;
             _sourceUnit = compilerContext.SourceUnit;
         }
 
@@ -63,6 +65,10 @@
             get { return _debugCompiler; }
         }
 
+        public bool TraceEnabled {
+            get { return _traceEnabled; }
+        }
+
         public SourceUnit/*!*/ SourceUnit {
             get { return _sourceUnit; }
         }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;C448766
File: MethodDeclaration.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;C448766  (server)    5/28/2008 3:56 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Compiler/Ast/Declarations/MethodDeclaration.cs;Trace
@@ -91,7 +91,7 @@
             MSA.Expression[] parameters = DefineParameters(gen, methodBlock);
             MSA.Expression currentMethodVariable = methodBlock.CreateLocalVariable("#method", typeof(RubyMethodInfo));
             MSA.Expression rfcVariable = methodBlock.CreateLocalVariable("#rfc", typeof(RuntimeFlowControl));
-            MSA.Expression scopeVariable = methodBlock.CreateLocalVariable("#scope", typeof(RubyScope));
+            MSA.Expression scopeVariable = methodBlock.CreateLocalVariable("#scope", typeof(RubyMethodScope));
             MSA.Expression selfParameter = parameters[0];
             MSA.Expression blockParameter = parameters[1];
 
@@ -121,6 +121,7 @@
                 Ast.Block(
                     Ast.Assign(currentMethodVariable, methodDefinitionVariable),
                     _parameters.TransformOptionalsInitialization(gen),
+                    gen.TraceEnabled ? AstFactory.OpCall("TraceMethodCall", scopeVariable, Ast.Constant(gen.SourceUnit.Path), Ast.Constant(Location.Start.Line)) : Ast.Empty(),
                     Body.TransformToStatement(gen, ResultOperation.Return)
                 )
             );
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyEngineOptions.cs;C438696
File: RubyEngineOptions.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyEngineOptions.cs;C438696  (server)    5/28/2008 1:24 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyEngineOptions.cs;Trace
@@ -32,6 +32,7 @@
         private string[] _arguments;
         private string _mainFile;
         private bool _showWarnings;
+        private bool _enableTracing;
         private readonly List<string>/*!*/ _requiredLibraries;
 
         public string[] Arguments {
@@ -49,6 +50,11 @@
             set { _showWarnings = value; }
         }
 
+        public bool EnableTracing {
+            get { return _enableTracing; }
+            set { _enableTracing = value; }
+        }
+        
         public List<string>/*!*/ RequiredLibraries {
             get { return _requiredLibraries; }
         }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C448462
File: RubyOptionsParser.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;C448462  (server)    5/28/2008 1:23 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Hosting/RubyOptionsParser.cs;Trace
@@ -120,6 +120,10 @@
                     ((RubyContext)HostingHelpers.GetLanguageContext(Engine)).ExecutionContext.Loader.InsertLoadPaths(path.Split(System.IO.Path.PathSeparator));
                     break;
 
+                case "-trace":
+                    _engineOptions.EnableTracing = true;
+                    break;
+
                 default:
                     base.ParseArgument(arg);
                     if (ConsoleOptions.FileName != null) {
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C448766
File: RubyContext.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;C448766  (server)    5/28/2008 3:52 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyContext.cs;Trace
@@ -109,7 +109,7 @@
             }
 
             return ast.Transform(
-                new AstGenerator(context, Snippets.Shared.SaveSnippets, DomainManager.GlobalOptions.DebugMode),
+                new AstGenerator(context, Snippets.Shared.SaveSnippets, DomainManager.GlobalOptions.DebugMode, EngineOptions.EnableTracing),
                 context.SourceUnit.Kind
             );
         }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C450567
File: RubyExecutionContext.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;C450567  (server)    5/28/2008 1:47 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyExecutionContext.cs;Trace
@@ -76,7 +76,11 @@
         private readonly RuntimeErrorSink/*!*/ _runtimeErrorSink;
         private readonly RubyInputProvider/*!*/ _inputProvider;
         private readonly Dictionary<SymbolId, GlobalVariable>/*!*/ _globalVariables;
+        private Proc _traceListener;
 
+        [ThreadStatic]
+        private bool _traceListenerSuspended;
+
         private EqualityComparer _equalityComparer;
 
         /// <summary>
@@ -134,7 +138,8 @@
         private DynamicSite<object, SymbolId, object> _singletonMethodRemovedCallbackSite;
         private DynamicSite<object, SymbolId, object> _singletonMethodUndefinedCallbackSite;
         private DynamicSite<RubyClass, RubyClass, object> _classInheritedCallbackSite;
-
+        private DynamicSite<Proc, RubyArray, object> _traceListenerCallbackSite;
+        
         public Exception CurrentException {
             get { return _currentException; } 
             set { _currentException = value; } 
@@ -168,6 +173,11 @@
             set { _itemSeparator = value; }
         }
 
+        public Proc TraceListener {
+            get { return _traceListener; }
+            set { _traceListener = value; } 
+        }
+
         public IEnumerable<KeyValuePair<SymbolId, GlobalVariable>>/*!*/ GlobalVariables {
             get { return _globalVariables; }
         }
@@ -1338,6 +1348,34 @@
             _classInheritedCallbackSite.Invoke(_context.EmptyContext, superClass, subClass);
         }
 
+        internal void MethodCalled(RubyMethodScope/*!*/ scope, string fileName, int lineNumber) {
+            if (_traceListener != null && !_traceListenerSuspended) {
+                if (!_traceListenerCallbackSite.IsInitialized) {
+                    _traceListenerCallbackSite.EnsureInitialized(CallAction.Make(RubyContext.RubyBinder, 
+                        new CallSignature(ArgumentKind.List)));
+                }
+                
+                try {
+                    _traceListenerSuspended = true;
+
+                    RubyArray args = new RubyArray();
+                    args.Add(MutableString.Create("call"));             // event
+                    args.Add(fileName);                                 // file
+                    args.Add(RuntimeHelpers.Int32ToObject(lineNumber)); // line
+                    args.Add(scope.Method.DefinitionName);              // TODO: alias
+                    args.Add(new Binding(scope));                       // binding
+
+                    RubyModule module = scope.Method.DeclaringModule;
+                    args.Add(module.IsSingletonClass ? ((RubyClass)module).SingletonClassOf : module); // module
+
+                    _traceListenerCallbackSite.Invoke(scope, _traceListener, args);
+
+                } finally {
+                    _traceListenerSuspended = false;
+                }
+            }
+        }
+
         #endregion
     }
 }
===================================================================
edit: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C449929
File: RubyOps.cs
===================================================================
--- $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;C449929  (server)    5/28/2008 1:27 PM
+++ Shelved Change: $/Dev10/feature/vs_langs01/Merlin/Main/Languages/Ruby/Ruby/Runtime/RubyOps.cs;Trace
@@ -202,6 +202,11 @@
             return result;
         }
 
+        public static void TraceMethodCall(RubyMethodScope/*!*/ scope, string fileName, int lineNumber) {
+            //RubyMethodScope scope = (RubyMethodScope)context;
+            scope.ExecutionContext.MethodCalled(scope, fileName, lineNumber);
+        }
+
         // emitted:
         public static CodeContext/*!*/ CreateBlockScope(ILocalVariables/*!*/ locals, CodeContext/*!*/ parent, bool isVisible) {
             RubyScope p = (RubyScope)parent;
===================================================================
