在(1)中介绍了DSL和普通的函数定义之间的区别。在(1)的最后提到,DSL分为内部DSL和外部DSL,我们再看一遍他们的定义:1. External DSLs 用不同于host语言的语言来编写,通过编译和解释器来翻译成host语言 2. Internal DSLs 将host语言转化为DSL本身。
第二种方式,相比较第一种来说,构建DSL更为简便,还可以利用host语言本身已有的语言特征和库等,缺点是定义DSL的时候会受到host语言的限制。但是,如果我们选择了一门语法友好、灵活的编程语言作为host语言的话,那么我们就可以放大内部DSL的优点,弱化它的缺点,最终达到效率和回报的最佳值,那么Ruby是一个好的选择。
Why Ruby?Obie
Fernandez 在InfoQ论坛上列出了Ruby的一些feature:
![](http://dl.iteye.com/upload/attachment/591938/158a64bd-2519-36df-8aac-a99005278da8.jpg)
当然了,Ruby的语法有很多值得玩味的地方,比如。。。(也许这需要好几篇文章来写了)。好吧,让我们直接一点:Ruby DSL的强大直接来自于Ruby强大的元编程能力。
“元”这个词来源于希腊语中表示”…之间, …之后, …超越’的前缀 ”meta”,有”超越”和”高阶”的意思。正如”元数据”表示”数据的数据”, “元模型”表示”模型的模型”, “元编程”表示”编程的编程”。
在《programming ruby 1.9》中说过:” Programming is all about building layers of abstractions.” 有些语言,比如C语言,更接近与机器本身,从而导致C语言跟应用之间的距离比较遥远。而有些语言,比如Ruby,提供了更高层次的抽象,从而让你在更接近于特定领域的地方开始编程。但是,当你使用元编程时,你就不再局限于语言本身的抽象层次了,你可以基于母语言构建新的抽象。于是,” In effect, you’re creating a new, domain-specific programming language—one that’s designed to let you express the concepts you need to solve your particular problem.”
所以,从这个角度看,元编程是DSL的基础。几乎每一种Ruby DSL的实现都离不开元编程。下面我归纳一下Ruby DSL的几种方式以及其中利用到的元编程技巧:
1. Class Marcos
![](http://dl.iteye.com/upload/attachment/591940/06532e99-252b-37a7-a3ac-0256ee929103.jpg)
你可以把”ofter_create”, ”has_many”看做一种声名。它的实现依赖于元编程中反射功能中的define_method或者instance_eval, 可以为函数动态添加方法。
2. Methods on an Object
![](http://dl.iteye.com/upload/attachment/591943/98765294-ee3f-35db-b807-3bd9ece9980d.jpg)
=>
![](http://dl.iteye.com/upload/attachment/591945/89ddfd97-27d7-3e7a-aaca-3fa835f2ebd2.jpg)
这是一种构造层次数据的DSL,完全基于Builder::XmlMarkup的对象。我们可以发现,生成的XML中定义的关键字完全可以由对象的方法名来决定,但是这个对象是如何做到满足所有任意添加的关键字呢?这其中的实现就依赖于元编程中反射功能中的method_missing方法。
3. 自定义词汇
![](http://dl.iteye.com/upload/attachment/591952/6fd0367e-a408-3225-83ea-cb2c435cb9f5.jpg)
在Ruby on Rails中,你可以:
4.years
+ 13.days +
2.hours
或者我们可以为这些词汇定义上下文:
![](http://dl.iteye.com/upload/attachment/591950/6cf8b21b-0993-3355-a4ac-2a8b4a731535.jpg)
第一种你可以叫做”自定义词汇”,第二种你可以叫做”单位的实现”,第三种你可以叫做”上下文相关的词汇”,但是本质上他们都是一样的。由于Ruby中没有函数,只有方法,意味着所有方法的使用都关联到一个对象。第一种实现,实际上调用者是Object的对象,第二种,调用者是4,13,2这些Fixnum的对象,第三种实现通过关键字task之后的关键字来调用不同的对象来调用这些方法。
这些DSL的实现依赖于Ruby开放类,block(其实相当于高阶函数)等特性。
基本上Ruby的DSL都是基于以上三种模式的组合和扩展,当然其实现背后的技巧可以非常不同和巧妙。
(文章转载请注明出处)
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1938/158a64bd-2519-36df-8aac-a99005278da8-thumb.jpg)
- 大小: 52.3 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1940/06532e99-252b-37a7-a3ac-0256ee929103-thumb.jpg)
- 大小: 14.5 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1943/98765294-ee3f-35db-b807-3bd9ece9980d-thumb.jpg)
- 大小: 16.8 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1945/89ddfd97-27d7-3e7a-aaca-3fa835f2ebd2-thumb.jpg)
- 大小: 21.7 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1950/6cf8b21b-0993-3355-a4ac-2a8b4a731535-thumb.jpg)
- 大小: 20.3 KB
![点击查看原始大小图片](http://dl2.iteye.com/upload/attachment/0059/1952/6fd0367e-a408-3225-83ea-cb2c435cb9f5-thumb.jpg)
- 大小: 11.7 KB
分享到:
相关推荐
这使得Ruby非常适合构建自定义的DSL(领域特定语言),如Ruby on Rails框架中的路由配置。 Ruby on Rails,简称Rails,是一个基于Ruby的开源Web应用框架,遵循MVC(模型-视图-控制器)架构模式。Rails强调“约定...
- **编程接口**:介绍编程接口的使用方法,使开发者能够灵活地集成WebSphere MQ于各类应用程序之中。 - **扩展功能与高级技巧**:包括日志管理、死信处理、客户端、群集、交易、触发、报告、事件、分段与分组、分发...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
4. **领域特定语言(DSL)构造**:Groovy非常适合创建内部DSL,可以用来简化特定领域的代码,如配置文件或构建脚本。 5. **元编程**:Groovy支持元编程,允许在运行时修改类或对象的行为,增强了灵活性。 Grails的...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
JCaptcha4Struts2 是一个 Struts2的插件,用来增加验证码的支持,使用时只需要用一个 JSP 标签 (<jcaptcha:image label="Type the text "/> ) 即可,直接在 struts.xml 中进行配置,使用强大的 JCaptcha来生成验证码...
3. **查询构造**:Hermes.cr 可能提供了一套构建查询的 DSL(Domain Specific Language),使开发者能够用 Crystal 语法构建复杂的 Elasticsearch 查询。 4. **性能优化**:由于 Crystal 语言的高性能特性,Hermes....