非常教程

Ruby 2.4参考手册

追踪点 | TracePoint

TracePoint

Parent:Object

一个在良好的面向对象API中提供Kernel#set_trace_func功能的类。

示例

我们可以使用TracePoint专门收集异常信息:

trace = TracePoint.new(:raise) do |tp|
    p [tp.lineno, tp.event, tp.raised_exception]
end
#=> #<TracePoint:disabled>

trace.enable
#=> false

0 / 0
#=> [5, :raise, #<ZeroDivisionError: divided by 0>]

事件

如果您未指定要侦听的事件类型,则TracePoint将包含所有可用事件。

请注意,不要依赖当前的事件集,因为此列表可能会更改。相反,建议您指定要使用的事件类型。

要过滤所追踪的内容,您可以将以下任何内容传递给events

:line

在新行上执行代码

:class

启动一个类或模块定义

:end

完成一个类或模块的定义

:call

调用Ruby方法

:return

从Ruby方法返回

:c_call

调用一个C语言例程

:c_return

从C语言例程返回

:raise

引发异常

:b_call

事件挂钩在块入口处

:b_return

在块结尾的事件挂钩

:thread_begin

线程开始处的事件挂钩

:thread_end

线程结束时的事件挂钩

:fiber_switch

光纤交换机上的事件挂钩

公共类别方法

new(*events) { |obj| block } → obj Show source

返回一个新的TracePoint对象,默认情况下不启用。

接下来,为了激活跟踪,你必须使用#enable

trace = TracePoint.new(:call) do |tp|
    p [tp.lineno, tp.defined_class, tp.method_id, tp.event]
end
#=> #<TracePoint:disabled>

trace.enable
#=> false

puts "Hello, TracePoint!"
# ...
# [48, IRB::Notifier::AbstractNotifier, :printf, :call]
# ...

如果要停用跟踪,则必须使用#disable

trace.disable

请参阅TracePoint的活动以了解可能发生的事件和更多信息。

必须给出一个块,否则会引发一个ThreadError。

如果跟踪方法未包含在给定的事件过滤器中,则会引发RuntimeError。

TracePoint.trace(:line) do |tp|
    p tp.raised_exception
end
#=> RuntimeError: 'raised_exception' not supported by this event

如果在块外调用跟踪方法,则会引发RuntimeError。

TracePoint.trace(:line) do |tp|
  $tp = tp
end
$tp.line #=> access from outside (RuntimeError)

从其他线程访问也被禁止。

static VALUE
tracepoint_new_s(int argc, VALUE *argv, VALUE self)
{
    rb_event_flag_t events = 0;
    int i;

    if (argc > 0) {
        for (i=0; i<argc; i++) {
            events |= symbol2event_flag(argv[i]);
        }
    }
    else {
        events = RUBY_EVENT_TRACEPOINT_ALL;
    }

    if (!rb_block_given_p()) {
        rb_raise(rb_eThreadError, "must be called with a block");
    }

    return tracepoint_new(self, 0, events, 0, 0, rb_block_proc());
}

stat → obj Show source

返回TracePoint的内部信息。

返回值的内容是特定于实现的。将来可能会改变。

此方法仅用于调试TracePoint本身。

static VALUE
tracepoint_stat_s(VALUE self)
{
    rb_vm_t *vm = GET_VM();
    VALUE stat = rb_hash_new();

    tracepoint_stat_event_hooks(stat, vm->self, vm->event_hooks.hooks);
    /* TODO: thread local hooks */

    return stat;
}

trace(*events) { |obj| block } → obj Show source

::new的便捷方法,可以自动激活跟踪。

trace = TracePoint.trace(:call) { |tp| [tp.lineno, tp.event] }
#=> #<TracePoint:enabled>

trace.enabled? #=> true
static VALUE
tracepoint_trace_s(int argc, VALUE *argv, VALUE self)
{
    VALUE trace = tracepoint_new_s(argc, argv, self);
    rb_tracepoint_enable(trace);
    return trace;
}

公共实例方法

binding() Show source

从事件返回生成的绑定对象

static VALUE
tracepoint_attr_binding(VALUE tpval)
{
    return rb_tracearg_binding(get_trace_arg());
}

callee_id() Show source

返回被调用方法的被调用名称

static VALUE
tracepoint_attr_callee_id(VALUE tpval)
{
    return rb_tracearg_callee_id(get_trace_arg());
}

defined_class() Show source

返回被调用方法的类或模块。

class C; def foo; end; end
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class #=> C
end.enable do
  C.new.foo
end

如果方法由模块定义,则返回该模块。

module M; def foo; end; end
class C; include M; end;
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class #=> M
end.enable do
  C.new.foo
end

注意: defined_class返回单例类。

Kernel#set_trace_func的第6个块参数传递由singleton类附加的原始类。

这是 Kernel#set_trace_func TracePoint 之间的区别。

class C; def self.foo; end; end
trace = TracePoint.new(:call) do |tp|
  p tp.defined_class #=> #<Class:C>
end.enable do
  C.foo
end
static VALUE
tracepoint_attr_defined_class(VALUE tpval)
{
    return rb_tracearg_defined_class(get_trace_arg());
}

disable → true or false Show source

disable { block } → obj

取消激活跟踪

如果跟踪已启用,则返回true。如果跟踪被禁用,则返回false。

trace.enabled?       #=> true
trace.disable        #=> false (previous status)
trace.enabled?       #=> false
trace.disable        #=> false

如果给出了一个块,那么只会在该块的范围内禁用跟踪。

trace.enabled?
#=> true

trace.disable do
    trace.enabled?
    # only disabled for this block
end

trace.enabled?
#=> true

注意:您不能访问块内的事件挂钩。

trace.disable { p tp.lineno }
#=> RuntimeError: access from outside
static VALUE
tracepoint_disable_m(VALUE tpval)
{
    rb_tp_t *tp = tpptr(tpval);
    int previous_tracing = tp->tracing;
    rb_tracepoint_disable(tpval);

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, Qnil,
                         previous_tracing ? rb_tracepoint_enable : rb_tracepoint_disable,
                         tpval);
    }
    else {
        return previous_tracing ? Qtrue : Qfalse;
    }
}

enable → true or false Show source

enable { block } → obj

激活跟踪

如果跟踪已启用,则返回true。如果跟踪被禁用,则返回false。

trace.enabled?  #=> false
trace.enable    #=> false (previous state)
                #   trace is enabled
trace.enabled?  #=> true
trace.enable    #=> true (previous state)
                #   trace is still enabled

如果给出了一个块,跟踪将只在该块的范围内启用。

trace.enabled?
#=> false

trace.enable do
    trace.enabled?
    # only enabled for this block
end

trace.enabled?
#=> false

注意:您不能访问块内的事件挂钩。

trace.enable { p tp.lineno }
#=> RuntimeError: access from outside
static VALUE
tracepoint_enable_m(VALUE tpval)
{
    rb_tp_t *tp = tpptr(tpval);
    int previous_tracing = tp->tracing;
    rb_tracepoint_enable(tpval);

    if (rb_block_given_p()) {
        return rb_ensure(rb_yield, Qnil,
                         previous_tracing ? rb_tracepoint_enable : rb_tracepoint_disable,
                         tpval);
    }
    else {
        return previous_tracing ? Qtrue : Qfalse;
    }
}

enabled? → true or false Show source

跟踪的当前状态

VALUE
rb_tracepoint_enabled_p(VALUE tpval)
{
    rb_tp_t *tp = tpptr(tpval);
    return tp->tracing ? Qtrue : Qfalse;
}

event() Show source

事件类型

请参阅TracePoint事件以获取更多信息。

static VALUE
tracepoint_attr_event(VALUE tpval)
{
    return rb_tracearg_event(get_trace_arg());
}

inspect → string Show source

返回一个包含人类可读的TracePoint状态的字符串。

static VALUE
tracepoint_inspect(VALUE self)
{
    rb_tp_t *tp = tpptr(self);
    rb_trace_arg_t *trace_arg = GET_THREAD()->trace_arg;

    if (trace_arg) {
        switch (trace_arg->event) {
          case RUBY_EVENT_LINE:
          case RUBY_EVENT_SPECIFIED_LINE:
            {
                VALUE sym = rb_tracearg_method_id(trace_arg);
                if (NIL_P(sym))
                    goto default_inspect;
                return rb_sprintf("#<TracePoint:%"PRIsVALUE"@%"PRIsVALUE":%d in `%"PRIsVALUE"'>",
                                  rb_tracearg_event(trace_arg),
                                  rb_tracearg_path(trace_arg),
                                  FIX2INT(rb_tracearg_lineno(trace_arg)),
                                  sym);
            }
          case RUBY_EVENT_CALL:
          case RUBY_EVENT_C_CALL:
          case RUBY_EVENT_RETURN:
          case RUBY_EVENT_C_RETURN:
            return rb_sprintf("#<TracePoint:%"PRIsVALUE" `%"PRIsVALUE"'@%"PRIsVALUE":%d>",
                              rb_tracearg_event(trace_arg),
                              rb_tracearg_method_id(trace_arg),
                              rb_tracearg_path(trace_arg),
                              FIX2INT(rb_tracearg_lineno(trace_arg)));
          case RUBY_EVENT_THREAD_BEGIN:
          case RUBY_EVENT_THREAD_END:
            return rb_sprintf("#<TracePoint:%"PRIsVALUE" %"PRIsVALUE">",
                              rb_tracearg_event(trace_arg),
                              rb_tracearg_self(trace_arg));
          default:
          default_inspect:
            return rb_sprintf("#<TracePoint:%"PRIsVALUE"@%"PRIsVALUE":%d>",
                              rb_tracearg_event(trace_arg),
                              rb_tracearg_path(trace_arg),
                              FIX2INT(rb_tracearg_lineno(trace_arg)));
        }
    }
    else {
        return rb_sprintf("#<TracePoint:%s>", tp->tracing ? "enabled" : "disabled");
    }
}

lineno() Show source

活动的行号

static VALUE
tracepoint_attr_lineno(VALUE tpval)
{
    return rb_tracearg_lineno(get_trace_arg());
}

method_id() Show source

在被调用方法的定义处返回名称

static VALUE
tracepoint_attr_method_id(VALUE tpval)
{
    return rb_tracearg_method_id(get_trace_arg());
}

path() Show source

正在运行的文件的路径

static VALUE
tracepoint_attr_path(VALUE tpval)
{
    return rb_tracearg_path(get_trace_arg());
}

raised_exception() Show source

来自:raise事件的异常值

static VALUE
tracepoint_attr_raised_exception(VALUE tpval)
{
    return rb_tracearg_raised_exception(get_trace_arg());
}

return_value() Show source

返回值从:returnc_returnb_return事件

static VALUE
tracepoint_attr_return_value(VALUE tpval)
{
    return rb_tracearg_return_value(get_trace_arg());
}

self() Show source

在事件期间返回跟踪对象

与#binding相同:

trace.binding.eval('self')
static VALUE
tracepoint_attr_self(VALUE tpval)
{
    return rb_tracearg_self(get_trace_arg());
}

追踪点 | TracePoint相关

Ruby 2.4

Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。

主页 https://www.ruby-lang.org/
源码 https://github.com/ruby/ruby
版本 2.4
发布版本 2.4.1

Ruby 2.4目录

1.缩略 | Abbrev
2.ARGF
3.数组 | Array
4.Base64
5.基本对象 | BasicObject
6.基准测试 | Benchmark
7.BigDecimal
8.绑定 | Binding
9.CGI
10.类 | Class
11.比较 | Comparable
12.负责 | Complex
13.计算续体 | Continuation
14.覆盖 | Coverage
15.CSV
16.日期 | Date
17.日期时间 | DateTime
18.DBM
19.代理 | Delegator
20.摘要 | Digest
21.Dir
22.DRb
23.编码 | Encoding
24.枚举 | Enumerable
25.枚举 | Enumerator
26.ENV
27.ERB
28.错误 | Errors
29.Etc
30.期望值 | Exception
31.错误类 | FalseClass
32.Fiber
33.Fiddle
34.文件 | File
35.文件实用程序 | FileUtils
36.查找 | Find
37.浮点 | Float
38.Forwardable
39.GC
40.GDBM
41.GetoptLong
42.Hash
43.Integer
44.IO
45.IPAddr
46.JSON
47.Kernel
48.语言 | 3Language
49.记录 | Logger
50.编排 | Marshal
51.MatchData
52.数学 | Math
53.矩阵 | Matrix
54.方法 | Method
55.模型 | Module
56.监控 | Monitor
57. 互斥 | Mutex
58.Net
59.Net::FTP
60.Net::HTTP
61.Net::IMAP
62.Net::SMTP
63.NilClass
64.数字 | Numeric
65.对象 | Object
66.ObjectSpace
67.Observable
68.Open3
69.OpenSSL
70.OpenStruct
71.OpenURI
72.OptionParser
73.路径名 | Pathname
74.完整输出 | PrettyPrint
75.Prime
76.Proc
77.过程 | Process
78.PStore
79.PTY
80.队列 | Queue
81.随机 | Random
82.范围 | Range
83.合理的 | Rational
84.Readline
85.Regexp
86.Resolv
87.Ripper
88.RubyVM
89.Scanf
90.SDBM
91.SecureRandom
92.Set
93.Shell
94.信号 | Signal
95.Singleton
96.套接字 | Socket
97.字符串 | String
98.StringIO
99.StringScanner
100.结构 | Struct