Ruby <<Ruby 元编程>>中的类宏怎么理解,还有帮忙解释下书中这段代码的执行过程。

mayday · 2013年03月14日 · 最后由 ugoa 回复于 2013年03月15日 · 6534 次阅读
  1. 类宏

    元编程中说:像attr_accessor()这样的方法成为类宏。而attr_accessor是拟态方法,那么拟态方法和类宏有什么区别?或者说类宏具体是怎么定义的?

  2. 下面这段代码的执行过程:

    class Book
    def title # ...
    end
    

def lend_to(user) puts "Lending to #{user}" # ... end

def self.deprecate(old_method, new_method) define_method(old_method) do |*args, &block| warn "Warning: #{old_method}() is deprecated. Use #{new_method}()." send(new_method, *args, &block) end end deprecate :GetTitle, :title deprecate :LEND_TO_USER, :lend_to deprecate :title2, :subtitle end

b = Book.new b.LEND_TO_USER("Bill")

>> Warning: LEND_TO_USER() is deprecated. Use lend_to().

>> Lending to Bill


(1)  **当实例化(Book.new)时有没有调用哪个方法?**
(2)  **在调用b.LEND_TO_USER("Bill")时,具体是怎么运行的,没看懂具体的执行步骤。**

<<Ruby元编程>>p115,这段代码p47也有段类似的。

1)实例化的时候没有调用上面的方法,但是在定义 Book 这个类是已经执行了这些方法

 deprecate(:GetTitle, :title)
...

2)LEND_TO_USER 是通过 deprecate :LEND_TO_USER, :lend_to 在定义这个类时一起定义出来的。具体可以看 define_method 这个方法

类宏我觉得应该是在定义类时执行的代码,如 deprecate(:GetTitle, :title),最简单的是

class A
  puts 'hello'
end

拟态方法不知道是什么,建议读原版书。

#1 楼 @cantin (1)在定义 Book 这个类执行了这些方法,是讲的通,但还是觉得从原理上有点不太理解,明天再看看文档 (2)拟态方法:一个方法调用把自己伪装成另外一种东西。比如说putsobj.myattributer=,明明是方法,但伪装成了关键字。 感觉类宏这样理解貌似不太对吧,我表示有点混淆了~~~

代码没有那么复杂,恐怕更多的是让这些中文名字给搞晕了。最好还是读英文吧。

同意@cantin.@yanhao 翻译过程中,新名词太多,造成概念混淆。 1,看英文版。2,你试试看下面的代码,自己理解下。 其实 ruby 就是分 class methods, instance_methods

class Book. ...省略... end

Book.methods # Book class 的 class methods,包括 deprecate Book.instance_methods # 包括 title, GetTitle, lend_to, LEND_TO_USER

所以,class method 在 class scope 中执行,load 完 class,就已经执行完成了。 执行 class method deprecate,就会调用 define_method,生成 instance_methods.

只有 instance_methods 才可以被 Book.new 的 instance 调用。

#4 楼 @ugoa 嗯嗯,讲的很清楚。类宏可以理解成如你所说的:在一个类定义中使用一个类方法,那么这个类方法就叫类宏。 并且,类宏在定义 class 时就会被执行,如:deprecate :GetTitle, :title 这样理解没什么问题吧。

#6 楼 @mayday 对的。还有,也不一定是在定义 class 时执行,在重新打开一个类对其修改时(像你这个例子)也是一样的。

#4 楼 @ugoa 嗯嗯,这块基本上理解了,thanks!

@mayday 我也正在看,可以交流下加深理解。 感觉这一段还是挺好理解的。 ruby 是解释型语言,所以Book.new之前的部分都执行过了一遍,也就是class, defin这些执行过了一遍,也就是类定义好了,但并没有调用。

rails c 是学习 rails 最快的途径

看回复很有启发@ugoa

#4 楼 @ugoa 回复很清晰,感谢。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号