【AICon】AI 基础设施、LLM运维、大模型训练与推理,一场会议,全方位涵盖! >>> 了解详情
写点什么

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:00768

评论

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

2021年证券类APP更新迭代监测专题分析(中)发布

易观分析

证券

YARN Federation技术解析及应用

移动云大数据

YARN

MBTI 剧透人生,你的天选职业是什么?(免费测)

融云 RongCloud

固定资产投资管理系统解决方案

低代码小观

资产管理 CRM系统 客户关系管理系统 企业设备管理 设备巡检管理系统

网络攻击盯上民生领域,应对DDoS和APT攻击,如何有效防御?

郑州埃文科技

IP地址 网络资产保护 网络攻击防御

《Mybatis 手撸专栏》第9章:细化XML语句构建器,完善静态SQL解析

小傅哥

源码分析 小傅哥 源码学习 手写Mybatis 源码实践

自助手动洗车设备洗车怎么样?

共享电单车厂家

自助洗车加盟 自助洗车机洗车 自助手动洗车设备

等保二级和等保三级的三大区别讲解-行云管家

行云管家

网络安全 等保 等级保护 等保2.0 等保二级

netty系列之:在netty中使用TCP协议请求DNS服务器

程序那些事

Java Netty 程序那些事 5月月更

从流量交换到共享联盟,开放银行如何助力金融数字转型?

CECBC

fastposter v2.8.2 发布 电商海报生成器

物有本末

智能汽车领域的开源软件供应链安全检测工具分享

墨菲安全

idea插件 工具分享 开源安全 墨菲安全 软件供应链

小区适合投放自助洗车机吗?

共享电单车厂家

自助洗车加盟 小区投放自助洗车机

前端监控的搭建步骤,别再一头雾水了!

杨成功

架构 大前端 5月月更

uniapp 如何将输入值转成大写

CRMEB

更全、更精准,美创科技实现Caché数据库M语言精细化审计

美创科技

cache 数据安全 数据库审计

为应用赋能!博云容器云产品族正式发布

BoCloud博云

容器 云原生 容器云

网页在线帮助中心的搭建策略

小炮

帮助中心

如何用Apifox 发送接口请求?

Liam

开发者 测试 后端 开发 Postman

Fastjson官方再次披露高危漏洞,包括rocketmq、jeecg-boot等近15%的github开源项目受影响

墨菲安全

安全 idea插件 Fastjson 依赖漏洞检测 墨菲安全

高危!Fastjson反序列化远程代码执行漏洞风险通告,请尽快升级

葡萄城技术团队

json 安全 Fastjson

没有店面店铺可以做自助洗车吗?

共享电单车厂家

自助洗车加盟 自助洗车店面

6月月更“粽”头戏,大家一起来参与吧!

InfoQ写作社区官方

热门活动 6月月更

互联网通信安全之终端数据保护

融云 RongCloud

以区块链技术推进应急管理体系现代化

CECBC

重磅首发!火线安全发布《云安全攻防技术期刊》

火线安全

安全 云安全

模块二

Geek_2ce415

是开自助洗车店还是传统洗车店好?

共享电单车厂家

自助洗车加盟 开自助洗车店 传统洗车店

避免惊群以及负载均衡的原理与具体实现

C++后台开发

nginx 负载均衡 后端开发 C++后台开发 惊群

英特尔开源项目推动SYCL标准采用,打破单个厂商封闭生态系统

科技之家

数字人民币智慧学生证来了,对于特定群体硬钱包或大有可为

CECBC

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