Ruby DSL介绍及其在测试数据构造中的使用(2)
?
在(1)中介绍了DSL和普通的函数定义之间的区别。在(1)的最后提到,DSL分为内部DSL和外部DSL,我们再看一遍他们的定义:1. External DSLs 用不同于host语言的语言来编写,通过编译和解释器来翻译成host语言 2. Internal DSLs 将host语言转化为DSL本身。
第二种方式,相比较第一种来说,构—SL更为简便,还可以利用host语言本身已有的语言特征和库等,缺点是定义DSL的时候会受到host语言的限制。但是,如果我们选择了一门语法友好、灵活的编程语言作为host语言的话,那么我们就可以放大内部DSL的优点,弱化它的缺点,最终达到效率和回报的最佳值,那么Ruby是一个好的选择。
Why Ruby?ObieFernandez 在InfoQ论坛上列出了Ruby的一些feature:
当然了,Ruby的语法有很多值得玩味的地方,比如。。。(也许这需要好几篇文章来写了)。好吧,让我们直接一点:Ruby DSL的强大直接来自于Ruby强大的元编程能力。
?
?
?
?你可以把”ofter_create”, ”has_many”看做一种声名。它的实现依赖于元编程中反射功能中的define_method或者instance_eval, 可以为函数动态添加方法。
?=>
?这是一种构造层次数据的DSL,完全基于Builder::XmlMarkup的对象。我们可以发现,生成的XML中定义的关键字完全可以由对象的方法名来决定,但是这个对象是如何做到满足所有任意添加的关键字呢?这其中的实现就依赖于元编程中反射功能中的method_missing方法。
?在Ruby on Rails中,你可以:
?第一种你可以叫做”自定义词汇”,第二种你可以叫做”单位的实现”,第三种你可以叫做”上下文相关的词汇”,但是本质上他们都是一样的。由于Ruby中没有函数,只有方法,意味着所有方法的使用都关联到一个对象。第一种实现,实际上调用者是Object的对象,第二种,调用者是4,13,2这些Fixnum的对象,第三种实现通过关键字task之后的关键字来调用不同的对象来调用这些方法。
这些DSL的实现依赖于Ruby开放类,block(其实相当于高阶函数)等特性。
?
基本上Ruby的DSL都是基于以上三种模式的组合和扩展,当然其实现背后的技巧可以非常不同和巧妙。
?
? ? ? ? (文章转载请注明出处)