在(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:

当然了,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


 你可以把”ofter_create”, ”has_many”看做一种声名。它的实现依赖于元编程中反射功能中的define_method或者instance_eval, 可以为函数动态添加方法。

2.  Methods on an Object


 =>


 这是一种构造层次数据的DSL,完全基于Builder::XmlMarkup的对象。我们可以发现,生成的XML中定义的关键字完全可以由对象的方法名来决定,但是这个对象是如何做到满足所有任意添加的关键字呢?这其中的实现就依赖于元编程中反射功能中的method_missing方法。

3.  自定义词汇


 在Ruby on Rails中,你可以:

4.years  +  13.days  +  2.hours

或者我们可以为这些词汇定义上下文:


  第一种你可以叫做”自定义词汇”,第二种你可以叫做”单位的实现”,第三种你可以叫做”上下文相关的词汇”,但是本质上他们都是一样的。由于Ruby中没有函数,只有方法,意味着所有方法的使用都关联到一个对象。第一种实现,实际上调用者是Object的对象,第二种,调用者是4,13,2这些Fixnum的对象,第三种实现通过关键字task之后的关键字来调用不同的对象来调用这些方法。

这些DSL的实现依赖于Ruby开放类,block(其实相当于高阶函数)等特性。

基本上Ruby的DSL都是基于以上三种模式的组合和扩展,当然其实现背后的技巧可以非常不同和巧妙。

(文章转载请注明出处)

Ruby DSL介绍及其在测试数据构造中的使用(2)相关推荐

  1. Ruby DSL介绍及其在测试数据构造中的使用(1)

    什么是DSL?英文全称Domain Specific Language,中文解释为领域专用语言.顾名思义,DSL是针对某个特定领域而开发的语言.像我们平时接触到的C/C++,Java,Python/R ...

  2. 第1部分: 游戏引擎介绍, 渲染和构造3D世界

    原文作者:Jake Simpson 译者: 向海 Email:GameWorldChina@myway.com  ------------------------------------------- ...

  3. 介绍 Spring 3.1 M1 中的缓存功能

    介绍 Spring 3.1 M1 中的缓存功能- 中文版 (转) Spring 3.1 提供了对已有的 Spring 应用增加缓存的支持,这个特性对应用本身来说是透明的,通过缓存抽象层,使得对已有代码 ...

  4. java程序设计专业介绍_简介Java编程中的Object类

    这篇文章主要介绍了简介Java编程中的Object类,是Java入门学习中的基础知识,需要的朋友可以参考下 Object 类位于 java.lang 包中,是所有 Java 类的祖先,Java 中的每 ...

  5. 介绍一种在Xcode中删除一整行代码的快捷键设置,

    介绍一种在Xcode中删除一整行代码的快捷键设置, 注:这里说的一整行不是你从行末尾按下 ⌘ + ⌫,而是说在行任何位置都可以删除. 在/Applications/Xcode.app/Contents ...

  6. java if 局部变量_java – 为什么局部变量在if-else构造中启动而在if-else-if构造中不启动?...

    所以我们知道必须初始化局部变量才能在if-else-if构造中使用. 例如,以下代码将无法编译. public class Test { public static void main (String ...

  7. 27.WLAN组网介绍_VLAN在WLAN业务中的应用

    WLAN组网介绍_VLAN在WLAN业务中的应用 VLAN在WLAN业务中的应用 一.VLAN的分类 1.管理VLAN 2.业务VLAN 3.用户VLAN 4.授权VLAN 总结 VLAN在WLAN业 ...

  8. 介绍一种在MATLAB中获取股市数据的方法

    介绍一种在MATLAB中获取股市数据的方法: >>clear >>c=yahoo 系统会返回 c = url: 'http://finance.yahoo.com'       ...

  9. 介绍磁性微球在各领域中的应用

    磁性高分子微球(简称磁性微球)是通过化学方法将有机高分子材料与无机磁性材料结合而形成的具有一定磁性及特殊结构的微球,既具有有机高分子材料的易加工和柔韧性,又具有无机材料的高密度和高力学性能,还可以通过 ...

最新文章

  1. OWASP TOP10(2017)
  2. 顶级生物信息学 RSS 订阅源
  3. 一个恶心的无法同步服务器与pda时间的龌龊问题
  4. 如何通过url访问的方式获取HANA report的元数据metadata
  5. 对于多属性类型系统的数据库设计
  6. socket-(2)
  7. SoundPool的sample 1 not READY问题
  8. 【转】SQLServer 行列互换
  9. STL源码剖析 阅读(一)
  10. 因子分析python代码_用Python实现因子分析
  11. 10 个超棒的 jQuery 视频插件
  12. JS:键盘事件(onkeydown 、onkeypress、 onkeyup三个)
  13. Selenium使用之——键盘操作方法
  14. 2次拒领诺贝尔奖,爱迪生嫉妒他才华,被美国政府列为绝密人物
  15. Kaggle-泰坦尼克号-机器学习/数据挖掘学习笔记
  16. Mr.张小白(案例:基于Spring MVC实现后台登陆系统验证)
  17. VBA案例8:实现在ppt中写vba,控制动态图
  18. 大数据开发到底要学哪些内容!加米谷告诉你
  19. centos安装JWM轻量桌面系统
  20. 《仙剑奇侠传四》完全攻略

热门文章

  1. OpenCV(基础补充)颜色空间HSV *args与**args(滑动条传参问题)
  2. xk3190串口通讯JAVA开发包_常用品牌plc通讯协议汇总学习
  3. 【进阶版九宫格背景图片】如何仅仅依靠background的几个属性组合搭配出酷炫的背景图片效果,并自适应任何宽高效果?
  4. SNMP introduction
  5. 《DDIA》读书笔记
  6. shell --- awk规范 系统总结
  7. 二叉树:最近的公共祖先 Lowest Common Ancestor of a Binary Tree
  8. 【php】【psr】psr2 编码风格规范
  9. Codeforces Round #447 (Div. 2) B. Ralph And His Magic Field 数学
  10. eclipse 重启/打开内置浏览器