这样的 dsl 很容易实现
build_after :some_server do |server| server.add_service :my_service end
如果想改为这样该怎么做呢?
build_after :some_server do add_service :my_service end
这样吗?
class Build def add_service(service) p "add service #{service}" end end def build_after(server, &block) Build.new.instance_eval(&block) if block_given? end build_after :some_server do add_service :my_service end
class Test def run(sym, &block) p sym instance_eval &block end def pp(str) p str end end t = Test.new t.run :hi do pp :world end
google
用 qor_dsl .... ;-)
https://github.com/qor/qor_dsl
@saiga 学习了,刚好最近也在写 dsl。
然后这样子写就好了
class Server::Configuration include Qor::Dsl node :build_after do node :my_service end end
#1 楼 @kenshin54 #2 楼 @saiga 多谢,1 楼的做法可以分离一个 builder 对象,有助于理清关系,2 楼的方法比较简洁 #5 楼 @zhangjinzhu 哈哈,这个也很方便,不过我先试试最原始的方式,然后再简化
太巧了。这正好是我刚刚学习完的 codeschool 中 Ruby Bit 2 中的 dsl part 1 章节的内容。obj.instance_eval(&block) 会将 &block 中的 self 设置为调用他的对象,所以可以省去原来的 server. add_service 的前缀直接调用 add_service, 相当与 self.add_service
#7 楼 @wppurking 看来我也要学习一下 codeschool 了,果然不学习要落后
我这里有一个统计分析框架 statlysis 配置的实际例子,也是用的 instance_eval ,https://github.com/mvj3/statlysis/blob/master/lib/statlysis.rb#L34
instance_eval
实际效果比如:
Statlysis.setup do set_database :local_statistic daily UserRecord.where(item_type: "activity") end
之前还有一个用来练手的 统计分析 DSL 设计,解决惰性加载 和 作用域 两个问题