|
|
1 得到所定义的实体的列表
ruby的反射api能够使我们在运行时检测类和对象。因此我们下面将会介绍Module, Class, 和Object中的定义的一些方法。
Module模块有一个constants 的方法,它将会返回系统中所有的常量名,包括类名和模块名。nesting 方法则是返回当前调用点上的嵌套的模块的列表.
list = Math.constants # ["E", "PI"]
Module#ancestors 返回指定的类或者模块的所有包含的类或者模块.
list = Array.ancestors# [Array, Enumerable, Object, Kernel]
class_variables 方法返回给定的类和他的超类的所有类变量的一个表。included_modules 方法列出包含在这个类中的所有模块。
class Parent @@var1 = nilendclass Child < Parent @@var2 = nilendlist1 = Parent.class_variables # ["@@var1"]list2 = Array.included_modules # [Enumerable, Kernel]
Class的方法instance_methods和public_instance_methods 是同义的。他们返回这个类的所有公有的方法。private_instance_methods和 protected_instance_methods 也就是返回私有和保护的实例方法。这几个方法都还带有一个参数,默认是true的。如果被设置为false,超类将不会被搜索。
n1 = Array.instance_methods.size # 121n2 = Array.public_instance_methods.size # 121n3 = Array.private_instance_methods.size # 71n4 = Array.protected_instance_methods.size # 0n5 = Array.public_instance_methods(falsee).size # 71
Object 类有很多操作实例的类似的方法。methods 方法将会返回这个对象的所有可以被调用的方法。调用 public_methods 方法,将会返回所有公有的方法。他也有一个参数来判断是否去父类搜索。private_methods, protected_methods,和singleton_methods 也都有类似的参数。
class SomeClass def initialize @a = 1 @b = 2 end def mymeth #... end protected :mymethendx = SomeClass.newdef x.newmeth # ...endiv = x.instance_variables # ["@b", "@a"]p x.methods.size # 42p x.public_methods.size # 41p x.public_methods(false).size # 1p x.private_methods.size # 71p x.private_methods(false).size # 1p x.protected_methods.size # 1p x.singleton_methods.size # 1
2 测试调用栈
有时我们想要知道我们的调用者是谁,这个有时是非常有用的。看下面的例子:
def func1 puts caller[0] enddef func2 func1endfunc2 # 打印出fucn1在那里被调用
3 监控程序的执行
一个ruby程序能够内省,或者说是检测他自己的执行。很多程序都用到了这个功能,有兴趣的话可以看看这几个ruby的源码:debug.rb, profile.rb, 和 tracer.rb。
我们能够使用 set_trace_func方法,他接受一个block作为参数。无论在程序的执行中发生任何事情时,这个block都会被调用,我们看下面的例子:
def meth(n) sum = 0 for i in 1..n sum += i end sumendset_trace_func(proc do |event, file, line, id, binding, klass, *rest| printf "%8s %s:%d %s/%s\n", event, file, line, klass, idend)meth(2)
可以看到输出类似这样的:
<div class="quote_title">引用 |
|