Ruby DSL与普通API的区别

时间:2009-10-12 23:45:49

标签: ruby design-patterns dsl

Ruby DSL的一些定义特征是什么,它将它与常规API分开?

6 个答案:

答案 0 :(得分:11)

使用API​​时,您需要以强制方式实例化对象并调用方法。另一方面,良好的DSL应该是声明性的,表示问题域中的规则和关系,而不是要执行的指令。此外,理想情况下,DSL应该是非程序员的可读性和可修改的(API不是这种情况)。

另请注意内部和外部DSL之间的区别。

  • 内部域特定语言嵌入在编程语言(例如Ruby)中。它易于实现,但DSL的结构取决于它所嵌入的父语言。
  • 外部域特定语言是一种针对特定域而设计的单独语言。它在语法方面为您提供了更大的灵活性,但您必须实现代码来解释它。它也更安全,因为编辑域规则的人无法访问母语的所有权力。

答案 1 :(得分:4)

DSL(域专用语言)是一个过度炒作的术语。如果您只是使用语言的子集(比如Ruby),那么它与原始语言的区别是什么?答案是,它不是。

但是,如果您对源文本进行一些预处理以引入新语法或核心语言中没有的新语义,那么您确实有一种新语言,可能是特定于域的。

答案 2 :(得分:2)

Ruby的诗歌模式和运算符重载的结合确实提供了同时具有合法的Ruby语法和合理的DSL的可能性。

XML的持续恶化确实表明,所有这些配置文件中内置的简单DSL可能并未完全被误导。

答案 3 :(得分:2)

创建DSL:

  • 向Object类添加新方法,以便您可以像调用内置语言一样调用它们。 (见rake)

  • 在自定义对象或对象集上创建方法,然后让脚本文件在顶级对象的上下文中运行语句。 (见capistrano)

API设计:

  • 在自定义对象或对象集上创建方法,以便用户创建一个对象以使用这些方法。

  • 将方法创建为类方法,以便用户在所有方法前面加上类名前缀。

  • 创建方法作为mixin,用户包含或扩展以使用自定义对象中的方法。

所以是的,他们之间的界线很薄。通过添加一个在正确的上下文中运行脚本文件的方法,将一组自定义对象转换为DSL是微不足道的。

答案 4 :(得分:1)

DSL和API之间的区别在于,如果没有被该域中的某人写为Ruby的子语言,则至少可以理解(并验证)DSL。

例如,您可以让财务分析师在Ruby DSL中为股票交易应用程序编写规则,他们永远不必知道他们使用的是Ruby。

答案 5 :(得分:1)

事实上,它们是同一件事。 DSL通常通过Ruby中的常规语言机制实现,因此从技术上讲,它们都是API。

然而,对于人们将某些东西识别为DSL,它通常最终会向现有类添加类似于声明性语句的内容。类似于ActiveRecord中的验证器和关系声明。

class Foo << ActiveRecord::Base
  validates_uniqueness_of :name
  validates_numericality_of :number, :integer_only => true

end

看起来像DSL,而以下不是:

class Foo <<ActiveRecord::BAse
  def validate
    unless unique? name
      errors.add(:name, "must be unique")
    end

    unless number.to_s.match?(/^[-]?\d$/)
      errors.add(:number, "must be an integer")
    end
  end
end

它们都将由普通的Ruby代码实现。只是看起来你有一个很酷的新语言结构,而另一个看起来相当行人(并且过于冗长等等)。