六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 44|回复: 0

Advanced Rails -

[复制链接]

升级  10%

15

主题

15

主题

15

主题

秀才

Rank: 2

积分
65
 楼主| 发表于 2013-1-27 05:20:50 | 显示全部楼层 |阅读模式
Introspection and ObjectSpace: Examining Data and Methods at Runtime

Ruby提供了很多方法用来在运行时查找对象。还有访问实例变量对象方法。使用他们的时候要当心,因为这些方法

破坏了封装。

class C  def initialize    @ivar = 1  endendc = C.newc.instance_variables              # => ["@ivar"]c.instance_variable_get(:@ivar)   # => 1c.instance_variable_set(:@ivar, 3) # => 3c.instance_variable_get(:@ivar)    # => 3

Object#methods方法返回实例方法的一个数组,包含了定义在接受者上的单例方法。如果这个方法的第一个参数是

false,则只返回对象的单例方法。

class C  def inst_method  end  def self.cls_method  endendc = C.newclass << c  def singleton_method  endendc.methods - Object.methods # => ["inst_method", "singleton_method"]c.methods(false) # => ["singleton_method"]


Module#instance_methods返回了类或者模块的实例方法。instance_methods是被class调用而methods是被实例调

用。给instance_methods传递一个false跳过了父类的方法:

C.instance_methods(false) # => ["inst_method"]

也可以用Metaid的metaclass来检查C的类方法:

C.metaclass.instance_methods(false) # => ["new", "allocate", "cls_method",                                          "superclass"]


In my experience, most of the value from these methods is in satisfying curiosity. With the

exception of a few well-established idioms, there is rarely a need in production code to reflect on

an object's methods. Far more often, these techniques can be used at a console prompt to find

methods available on an object—it's usually quicker than reaching for a reference book:

Array.instance_methods.grep /sort/ # => ["sort!", "sort", "sort_by"]


ObjectSpace

ObjectSpace是一个用来和Ruby的对象系统交互的模块。它有几个很有用的可以使底层hacking更轻松的模块方法:

    Garbage-collection methods: define_finalizer (sets up a callback to be called just before an object is destroyed), undefine_finalizer (removes those call-backs), and garbage_collect (starts garbage collection).

    _id2ref converts an object's ID to a reference to that Ruby object.

    each_object iterates through all objects (or all objects of a certain class) and yields them to a block.

尽管这些方法很有用,但是也很危险。慎重的使用他们。

在Ruby的Test::Unit框架里有个恰当的使用Objectspace的例子。代码用了ObjectSpace.each_object来列举所有存在的继承自Test::Unit::TestCase类。

test_classes = []ObjectSpace.each_object(Class) {  | klass |  test_classes << klass if (Test::Unit::TestCase > klass)}

不行的是,ObjectSpace是Ruby的虚拟机更加复杂化。特别是打开ObjectSpace打开的时候Jruby的性能受损很严重,因为Ruby的解析器不能直接的检查在JVM的内部数据的存在的对象。相反的,JRuby必须保持手工的跟踪对象,这将增加很多的消耗。相同的技巧可以在像Module.extended和Class.inherited的方法得到,这些不会有ObjectSpace更切实。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

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