写点什么

Obie Fernandez 谈敏捷 Ruby DSL

  • 2007-04-16
  • 本文字数:2107 字

    阅读完需:约 7 分钟

Software-Engineering Radio (一个向资深软件开发者提供音频节目的站点)最近就DSL(特定领域语言)和Ruby 语言如何使得编写内部DSL 变得更加方便等问题采访了InfoQ 的专家Obie Fernandez ,摘要如下:

DSL 是一种专注于某一特定领域的语言,使用通用语言(如 C 或者 Java)当然可以得到与 DSL 相同的功能。但是这样会产生大量繁琐的代码并导致大量的领域知识被隐藏在通用语言构造中(如 for 循环,if 条件,方法调用,import 声明等等)。

生成以及维护通用语言编写的代码本身也是问题所在:专家们必须将他们的知识变为代码。通常这些专家(销售人员,经理或者园丁)缺少编程知识,这意味着他们必须与程序员进行协作。当然,这也意味对代码的任何一次修改都包括许多繁琐的步骤:如果一个领域专家需要改变某些功能,她必须首先与程序员进行交流,由程序员实现这些修改,然后领域专家检查这些代码是否表现出期望的行为,诸如此类。

对于上述问题,其中一个可能的解决方案是开发一种适应特定环境的语言,非技术人员可以用它来解决问题。这种语言较通用语言更简洁并且仅仅提供目标领域所需要的类型以及特定的语言构造。

在访谈中, Obie 将 DSL 类比为自然语言中的俚语或者行话。全世界喜爱咖啡的人对下面这句话一定非常熟悉:

Venti half-caf, non-fat, no foam, no whip latte

在正常的对话中,上述语言不能传递正确的语义。并且世界上大多数的咖啡馆里可能仅仅提供最普通的牛奶加咖啡。但是在合适的场所使用上述语言(例如,星巴克),它将让你使用最少的词语喝到想要的饮料并且很少会造成误解。

有多种方式可以实现 DSL。其中一个选择是定义一种语法并使用解析器生成工具(如 ANTLR 或者 YACC)来生成解析器。通过它可以将 DSL 代码转化为某种可以被解释的数据结构(语法树)。其中一个例子是 Make 文件,它被用来定义构建过程(编译,打包,部署)。另一种方式是使用 XML 而不是解析器,它将对于解析器生成工具的依赖变为对于 XML 解析器的依赖,有许多工具可以用来支撑 XML 处理(使用 DOM 解析器可以得到类似语法树的数据结构,同时使用 XPATH 来提取数据,等等)。Ant,是一个基于 XML 的 DSL, 构建过程被定义为 XML 格式。Make 和 Ant 就是 _ 外部 _DSL 最典型的实现。

另一个解决方案是 _ 内部 _DSL, 它不需要使用任何解析器生成工具以及 XML 解析器,取而代之的是使用现有的合法的通用语言的构造,很明显,这种语言的构造必须非常灵活才可以容纳各种简练的 DSL 代码。

内部 DSL 的终极解决工具非 LISP 以及类 LISP 语言莫属,原因是 LISP 灵活的语法,它可以被概括为:

  • 原子
    几乎任何字符都可以成为原子,如foo:::bar:::甚至加号都是合法的原子
  • 零个或多个原子组成的序列
    放入圆括号中

LISP 宏特性使得开发者可以很轻易的在 LISP 中定义 DSL 并且将其解释或者展开为可以执行的通常的 LISP 代码。

另外一种适于使用内部 DSL 的语言是 Ruby, 没什么可惊奇的,想想 Ruby 丰富的语法吧,它是 Ruby 得以支持内部 DSL 的部分特性。下面是 Obie 在 PPT 上所使用到的观点以及相应的示例代码:

  • 方法调用中括号可以省略。这看起来没什么大不了的, 但是它使得下面的声明成为合法的 Ruby 代码: order = latte venti, half_caf, non_fat, no_foam, no_whip 在上面的例子中,latte(拿铁咖啡)以及我们所需要的特别的口味儿都是方法调用的一部分。latte 方法返回一个将咖啡各个属性进行了初始化的对象。

  • 类的定义在载入时可以被动态执行 class RuleSet < ActiveRecord::Base has_many :commends, :dependend => :delete_all # ... more... end 这是一个内部 DSL 在 Rails 的 ActiveRecord 中的例子。has_many 调用会在类第一次被载入时执行。这个调用被用来设定类的关联以及行为,例如,它可以通过 define_method 调用向类添加一些方法。这样这段 DSL 代码的用户可以使用非常简洁,描述性的方式来定义类某些方面的行为。事实上,这与 LISP 宏有很多相似的地方,他们都在代码被载入时进行工作。

  • 简洁的代码块书写格式(Block)块是自包含的 Ruby 代码。它可以被保存,当作参数传递并在以后执行,这个概念也被称做是匿名方法,lamda 演算或者闭包(Closures),在 Ruby 中向方法传递块非常简洁紧凑,它使得实现特定语言构造变得非常容易, Rake 是与 Make 和 Ant 非常相似的构建工具,我们来看一个例子:

    task :default => [:test] task :test do ruby "test/unittest.rb" end 上面的类使用了我们在这里提到的所有的三种概念。task 是一种方法调用,但是没有圆括号让它变的更具描述性。task 调用在载入时被执行,对内部数据结构进行设置。test 任务的逻辑在块中进行定义(在 do 和 end 之间的代码),并在适当的时候被执行。

在 Ruby 中,内部 DSL 使得编写简洁和描述性的规范变得非常容易。正如我们从 has_many 例子中看到的,内部 DSL 也可以很容易的与通常命令式的 Ruby 代码进行混合。

译者简介:胡凯是 InfoQ 中文站的志愿者翻译。2006 年加入 ThoughtWorks ,通过在 ThoughtWorks 多个国家和多个项目的敏捷实践,坚定地站在了敏捷阵营中,目前在进行 CruiseControl 相关的敏捷开源项目。他和许多敏捷开发者一样活跃在敏捷中国 CruiseControl-China 社区中。

2007-04-16 20:00864

评论

发布
暂无评论
发现更多内容

收藏!数据建模最全知识体系解读

华为云开发者联盟

数据仓库 数据 数据建模

开个交易所需要多少费用?数字货币交易所搭建

13530558032

基于SpringBoot、SpringCloud、Docker微服务架构实战,资源分享

Java架构之路

Java 程序员 架构 面试 编程语言

云算力矿机源码价格,区块链挖矿平台开发

13530558032

JVM入门,认识Class文件

Simon郎

JVM Java 分布式

胡继晔:中国应建区块链行业准入制度

CECBC

区块链 金融 数字经济

【云图说】第189期 初识数据仓库服务

华为云开发者联盟

数据库 数据仓库 数据

《迅雷链精品课》第五课:账户与账本

迅雷链

区块链

《Python程序员面试算法宝典》PDF 超清版免费领取

计算机与AI

Python 面试 算法

面试题总结--HashMap、Volatile相关

彭阿三

亚马逊全球百万钜惠引爆“黑五” 跨境狂欢“巅峰6日”震撼登场

爱极客侠

甲方日常 54

句子

工作 随笔杂谈 日常

LAXCUS大数据集群操作系统挖矿

陈泽云

大数据 分布式计算 挖矿

涛涌天际,水利万物:黄浦江畔读懂城市智能体

脑极体

阿里作为内部参考的Redis文档现在开放下载,姐夫半夜不睡都在看

小Q

Java redis 学习 编程 面试

KubeVela 正式开源:一个高可扩展的云原生应用平台与核心引擎

阿里巴巴云原生

阿里云 开源 Kubernetes 云原生 OAM

架构师Week5总结

lggl

总结

SQL数据库:GROUPING运算符

正向成长

GROUPING运算符

如何在 vuePress中添加博客导流公众号-即输入验证码解锁全站文章

itclanCoder

vuepress 解锁文章 博客引流 建站

区块链数字货币钱包源码价格,区块链多币种钱包

13530558032

天啊!怎么会有人把Spring Cloud微服务架构讲得这么透彻?

Java架构之路

Java 程序员 架构 面试 编程语言

Forrester 最新报告:阿里云稳居领导者地位,引领云原生开发浪潮

阿里巴巴云原生

阿里云 Serverless Kubernetes 容器 云原生

某美团程序员爆料:筛选简历时,用go语言的基本不看!网友:当韭菜还当出优越感了!

Java架构师迁哥

架构师Week5作业

lggl

作业

力扣(Leetcode)练习--给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序

Wynne

京东开发4年,想要跳槽去拼多多,落泪四4面,这年头跳槽可真难啊(还好不是裸辞)

Java~~~

架构 面试 编程语言 java架构师

太赞了!腾讯T3-3架构师整理了5000页的Java学习手册免费开放下载

Java架构之路

Java 程序员 架构 面试 编程语言

大四女学霸社招竟成功签约字节跳动,拿下30万年薪?

Java架构师迁哥

粉丝求助:JAVA程序员,4年了,很迷茫,希望前辈可以给指出一个技术路线和需掌握的知识技能树;

Java架构师迁哥

OpenFeign和Consul爱恨交织的两天

编号94530

Spring Cloud Consul OpenFegin spring 5

苹果首发ARM架构电脑芯片,将对PC格局带来哪些影响?

脑极体

Obie Fernandez谈敏捷Ruby DSL_Ruby_Werner Schuster_InfoQ精选文章