六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 63|回复: 0

ruby way之动态特性之二

[复制链接]

升级  98%

57

主题

57

主题

57

主题

秀才

Rank: 2

积分
197
 楼主| 发表于 2013-1-15 03:11:57 | 显示全部楼层 |阅读模式
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">引用
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表