浏览 10932 次
锁定老帖子 主题:领略一下ruby的DSL能力
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-05-05
class Topic < ActiveRecord::Base has_many :posts belongs_to :user end 那has_many和belongs_to究竟是什么东西呢?其实他们是Topic类的class method,标准写法是: class Topic < ActiveRecord::Base Topic.has_many(:posts) Topic.belongs_to(:user) end 那么has_many可以给我们带来什么呢?类方法has_many在被执行的时候,给Topic的对象实例添加了一系列方法:posts, posts<<, orders.push......等等。所以当我们在model里面声明has_many,belongs_to等对象关系的时候,一系列相关的对象方法就被自动添加进来了。 既然明白了rails的小把戏,让我们来自己试试看吧: module M def self.included(c) c.extend(G) end module G def generate_method(*args) args.each do |method_name| define_method(method_name) { puts method_name } end end end end class C include M generate_method :method1, :method2 end c = C.new c.method1 c.method2 我们定义了一个声明generate_method,可以接受多个symbol,来动态的创建同名的方法。现在我们在类C里面使用这个声明:generate_method :method1, :method2,当然我们需要include模块M。为什么rails的model不需要include相关的模块呢?当然是因为Topic的父类ActiveRecord::Base已经include了模块Associations了。 类C通过include模块M,调用了模块M的一个included回调接口,让类C去extend模块G,换句话来说就是,通过include模块M,来给类C动态添加一个类方法generate_method。 这个generate_method被定义在模块G当中,它接受一系列参数,来动态创建相关的方法。于是我们就实现了这样的DSL功能: 通过在类C里面声明generate_method :method1, :method2,让类C动态的添加了两个实例方法method1,method2,是不是很有意思? 实际上rails的对象关联声明也是以同样的方式实现的。 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2007-05-09
看了以后很有帮助!
|
|
返回顶楼 | |
发表时间:2007-06-01
请问robbin:
Topic.has_many(:posts) Topic.belongs_to(:user) 这两个类方法(以及其它类似的方法)是在什么地方定义的?? |
|
返回顶楼 | |
发表时间:2007-06-03
看看rails的源代码,
其中大量用到了method_missing 然后将params传到一个method generator函数中 动态地分析是否可以添加/定义这个函数 很powerful 不过,也使得代码不好读,太动态了 浅见 |
|
返回顶楼 | |
发表时间:2007-06-05
好像楼上的并没有回答我的问题咧?
|
|
返回顶楼 | |
发表时间:2007-06-14
请问robbin先生,您用的是什么文本编辑器,我也想用:)
看着挺舒服的。 |
|
返回顶楼 | |
发表时间:2007-06-17
lzqjj 写道 好像楼上的并没有回答我的问题咧?
To lzqjj: 這個嘛.. 事實上看看ActiveRecord的源代碼即可明瞭:) |
|
返回顶楼 | |
发表时间:2007-06-25
请Robbin解释一下,这两行方法在什么时候执行啊?搞不太懂耶。
|
|
返回顶楼 | |