[前][次][番号順一覧][スレッド一覧]

ruby-changes:26379

From: ko1 <ko1@a...>
Date: Tue, 18 Dec 2012 05:29:02 +0900 (JST)
Subject: [ruby-changes:26379] ko1:r38430 (trunk): * vm_trace.c (fill_id_and_klass): TracePoint#defined_class returns

ko1	2012-12-18 05:28:51 +0900 (Tue, 18 Dec 2012)

  New Revision: 38430

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=38430

  Log:
    * vm_trace.c (fill_id_and_klass): TracePoint#defined_class returns
      singleton class. `set_trace_func' passed attached class (which is
      attached/modified by singleton class) by 6th block parameter if it
      is singleton class. Previous behavior follows this spec.
      However, this method named `defined_class' should return singleton
      class directly because singleton methods are defined in singleton
      class. There are no compatible issue because TracePoint is introduced
      after 2.0.
      But compatiblity with `set_trace_func' is brokne. This means that
      you can not replace all `set_trace_func' code with TracePoint
      without consideration of this behavior.
      [Bug #7554]
    * test/ruby/test_settracefunc.rb: change a test to catch up
      an above chagne.

  Modified files:
    trunk/ChangeLog
    trunk/test/ruby/test_settracefunc.rb
    trunk/vm_trace.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 38429)
+++ ChangeLog	(revision 38430)
@@ -1,3 +1,21 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Tue Dec 18 04:58:22 2012  Koichi Sasada  <ko1@a...>
+
+	* vm_trace.c (fill_id_and_klass): TracePoint#defined_class returns
+	  singleton class. `set_trace_func' passed attached class (which is
+	  attached/modified by singleton class) by 6th block parameter if it
+	  is singleton class. Previous behavior follows this spec.
+	  However, this method named `defined_class' should return singleton
+	  class directly because singleton methods are defined in singleton
+	  class. There are no compatible issue because TracePoint is introduced
+	  after 2.0.
+	  But compatiblity with `set_trace_func' is brokne. This means that
+	  you can not replace all `set_trace_func' code with TracePoint
+	  without consideration of this behavior.
+	  [Bug #7554]
+
+	* test/ruby/test_settracefunc.rb: change a test to catch up
+	  an above chagne.
+
 Tue Dec 18 03:03:10 2012  Aaron Patterson <aaron@t...>
 
 	* ext/psych/lib/psych/visitors/to_ruby.rb: speed up node mapping so
Index: vm_trace.c
===================================================================
--- vm_trace.c	(revision 38429)
+++ vm_trace.c	(revision 38430)
@@ -716,9 +716,6 @@ fill_id_and_klass(rb_trace_arg_t *trace_ https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L716
 	    if (RB_TYPE_P(trace_arg->klass, T_ICLASS)) {
 		trace_arg->klass = RBASIC(trace_arg->klass)->klass;
 	    }
-	    else if (FL_TEST(trace_arg->klass, FL_SINGLETON)) {
-		trace_arg->klass = rb_iv_get(trace_arg->klass, "__attached__");
-	    }
 	}
 	else {
 	    trace_arg->klass = Qnil;
@@ -838,7 +835,36 @@ tracepoint_attr_method_id(VALUE tpval) https://github.com/ruby/ruby/blob/trunk/vm_trace.c#L835
 }
 
 /*
- * Return class or id from +:class+ event
+ * Return class or module the method being called.
+ *
+ *          class C; def foo; end; end
+ *	    trace = TracePoint.new(:call) do |tp|
+ *            tp.defined_class #=> C
+ *          end.enable do
+ *            C.new.foo
+ *          end
+ *
+ * If method is defined by a module, then returns that module.
+ *
+ *          module M; def foo; end; end
+ *          class C; include M; end;
+ *	    trace = TracePoint.new(:call) do |tp|
+ *            tp.defined_class #=> M
+ *          end.enable do
+ *            C.new.foo
+ *          end
+ *
+ * Note that TracePont#defined_class returns singleton class.
+ * 6th block parameter of `set_trace_func' passes original class
+ * of attached by singleton class. This is a difference between
+ * `set_trace_func' and TracePoint.
+ * 
+ *          class C; def self.foo; end; end
+ *	    trace = TracePoint.new(:call) do |tp|
+ *            tp.defined_class #=> #<Class:C>
+ *          end.enable do
+ *            C.foo
+ *          end
  */
 static VALUE
 tracepoint_attr_defined_class(VALUE tpval)
Index: test/ruby/test_settracefunc.rb
===================================================================
--- test/ruby/test_settracefunc.rb	(revision 38429)
+++ test/ruby/test_settracefunc.rb	(revision 38430)
@@ -418,12 +418,28 @@ class TestSetTraceFunc < Test::Unit::Tes https://github.com/ruby/ruby/blob/trunk/test/ruby/test_settracefunc.rb#L418
         :nothing
       end
     }
+    _defined_class = lambda{|tp|
+      klass = tp.defined_class
+      begin
+        # If it is singleton method, then return original class
+        # to make compatible with set_trace_func().
+        # This is very ad-hoc hack. I hope I can make more clean test on it.
+        case klass.inspect
+        when /Class:TracePoint/; return TracePoint
+        when /Class:Exception/; return Exception
+        else klass
+          klass
+        end
+      rescue Exception => e
+        e
+      end if klass
+    }
 
     trace = nil
     begin
     eval <<-EOF.gsub(/^.*?: /, ""), nil, 'xyzzy'
     1: trace = TracePoint.trace(*trace_events){|tp|
-    2:   events << [tp.event, tp.lineno, tp.path, tp.defined_class, tp.method_id, tp.self, tp.binding.eval("_local_var"), _get_data.(tp)]
+    2:   events << [tp.event, tp.lineno, tp.path, _defined_class.(tp), tp.method_id, tp.self, tp.binding.eval("_local_var"), _get_data.(tp)]
     3: }
     4: 1.times{|;_local_var| _local_var = :inner
     5:   tap{}

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]