2007-05-05
领略一下ruby的DSL能力
在rails里面,我们可以用很方便的声明方式来定义model之间的关联关系,例如:
那has_many和belongs_to究竟是什么东西呢?其实他们是Topic类的class method,标准写法是:
那么has_many可以给我们带来什么呢?类方法has_many在被执行的时候,给Topic的对象实例添加了一系列方法:posts, posts<<, orders.push......等等。所以当我们在model里面声明has_many,belongs_to等对象关系的时候,一系列相关的对象方法就被自动添加进来了。
既然明白了rails的小把戏,让我们来自己试试看吧:
我们定义了一个声明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的对象关联声明也是以同样的方式实现的。
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的对象关联声明也是以同样的方式实现的。
评论
zlxym
2007-06-25
请Robbin解释一下,这两行方法在什么时候执行啊?搞不太懂耶。
cfc
2007-06-17
lzqjj 写道
好像楼上的并没有回答我的问题咧?
To lzqjj:
這個嘛.. 事實上看看ActiveRecord的源代碼即可明瞭:)
云上的日子
2007-06-14
请问robbin先生,您用的是什么文本编辑器,我也想用:)
看着挺舒服的。
看着挺舒服的。
lzqjj
2007-06-05
好像楼上的并没有回答我的问题咧?
intelligent114
2007-06-03
看看rails的源代码,
其中大量用到了method_missing
然后将params传到一个method generator函数中
动态地分析是否可以添加/定义这个函数
很powerful
不过,也使得代码不好读,太动态了
浅见
其中大量用到了method_missing
然后将params传到一个method generator函数中
动态地分析是否可以添加/定义这个函数
很powerful
不过,也使得代码不好读,太动态了
浅见
lzqjj
2007-06-01
请问robbin:
Topic.has_many(:posts)
Topic.belongs_to(:user)
这两个类方法(以及其它类似的方法)是在什么地方定义的??
Topic.has_many(:posts)
Topic.belongs_to(:user)
这两个类方法(以及其它类似的方法)是在什么地方定义的??
melin
2007-05-09
看了以后很有帮助!
- 浏览: 1677857 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
我的相册
游乌镇
共 33 张
共 33 张
链接
最新评论
-
mod_rails尝鲜
我觉得还是mod_fcgid(不是mod_fastcgi)实际点
-- by zgd -
mod_rails尝鲜
hostingrails也已经提供mod_rails了
-- by leondu -
mod_rails尝鲜
dreamhost已经提供mod_rails了
-- by zgd -
关于JavaEye网站未来发展 ...
期待第三阶段目标的实现,但第三目标好像类似于google的云计算,建议赶紧开发, ...
-- by selectme_2008 -
总结一下大家对JavaEye网 ...
javaeye是我比较喜欢的一个网站,但盈利模式还是比较单一,让人怀疑网站是否能 ...
-- by selectme_2008






评论排行榜