simohayha 发表于 2013-1-15 03:11:57

ruby way之动态特性之二

1 得到所定义的实体的列表

ruby的反射api能够使我们在运行时检测类和对象。因此我们下面将会介绍Module, Class, 和Object中的定义的一些方法。

Module模块有一个constants 的方法,它将会返回系统中所有的常量名,包括类名和模块名。nesting 方法则是返回当前调用点上的嵌套的模块的列表.

list = Math.constants    # ["E", "PI"]

Module#ancestors 返回指定的类或者模块的所有包含的类或者模块.

list = Array.ancestors#

class_variables 方法返回给定的类和他的超类的所有类变量的一个表。included_modules 方法列出包含在这个类中的所有模块。

class Parent@@var1 = nilendclass Child < Parent@@var2 = nilendlist1 = Parent.class_variables   # ["@@var1"]list2 = Array.included_modules   #

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 SomeClassdef initialize    @a = 1    @b = 2enddef mymeth    #...endprotected :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 func1puts caller enddef func2func1endfunc2            # 打印出fucn1在那里被调用


3 监控程序的执行

一个ruby程序能够内省,或者说是检测他自己的执行。很多程序都用到了这个功能,有兴趣的话可以看看这几个ruby的源码:debug.rb, profile.rb, 和 tracer.rb。

我们能够使用 set_trace_func方法,他接受一个block作为参数。无论在程序的执行中发生任何事情时,这个block都会被调用,我们看下面的例子:

def meth(n)sum = 0for i in 1..n    sum += iendsumendset_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">引用
页: [1]
查看完整版本: ruby way之动态特性之二