您将如何在 Ruby 中设计这样的 DSL?

Posted

技术标签:

【中文标题】您将如何在 Ruby 中设计这样的 DSL?【英文标题】:How would you design such a DSL in Ruby? 【发布时间】:2011-04-12 03:33:26 【问题描述】:

我听说 Ruby 非常适合特定领域的语言。在过去的几个月里,我一直在创建一个 rpg 类型的浏览器游戏。在某些时候,我希望用户能够接受并完成任务。任务可以是任何东西,从杀死 x 数量的小怪,杀死一个突袭老板,也许是收集一些物品等等。

整个过程听起来很有趣,而且容易出错。我还认为为此创建一个 DSL 是个好主意。一种用简单语言描述任务的方法。但我没有太多经验。

你认为这是个好主意吗?如果是这样,您有什么建议/教程建议吗?

【问题讨论】:

【参考方案1】:

如果您正在设计 DSL,那么您可能需要花一些时间考虑您尝试将语言映射到的领域。 DSL 可以很好地删除重复的样板文件,否则你必须为每项任务编写,因此请专注于此。对于您的任务示例,您认为自己在任务之间需要哪些常见的东西?显然,很大程度上取决于任务如何在“幕后”实施。

我可以想象一个看起来像这样的任务:

Qwest "Retrieve the Grail" do
  given_by :pope

  description "Some hethan dragon took my cup, go get it back!"

  condition "Slay a dragon" do
     dragon.is_dead?
  end

  condition "Grab the Grail" do
     player.inventory.contains :grail
  end

  reward :phat_loot
end

在这里,DSL 可用于创建任务,为其命名、条件、奖励,并将其分配给任务提供者。

就编写 DSL 而言,您需要了解 ruby​​ 中的元编程。我知道为什么_the_lucky_stiff 已经写了一两篇关于它的文章,而辛酸的指南有一章关于它(Dwemthy’s Array in chapter 6)。就我个人而言,我总是很难理解为什么要写这些东西。我最终购买了Metaprogramming Ruby,我发现它真的很有用。

【讨论】:

这两个答案都对我有很大帮助,我会选择最好的。不过我必须选择一本,所以我会选择这本作为元编程书,这似乎也是一个不错的参考。 在 2012 年,每个人可能都不需要重新发明元编程并克服相同的障碍......也许检查 Docile gem 来实现 DSL? github.com/ms-ati/docile【参考方案2】:

这里是你的开胃菜:

module RPG
  def quest
    puts "starting your quest"
    yield
  end

  def move direction
    puts "moving to the #direction.to_s"
    yield if block_given?
  end

  def door action
    puts "#action.to_s door"
    yield if block_given?
  end
end

游戏编写者可以编写以下内容:

require 'rpg'

include RPG

quest do
  move :left
  move :right
  door :open do
    move :left
  end
end

运行产量:

> ruby game.rb 
starting your quest
moving to the left
moving to the right
opening door
moving to the left

【讨论】:

以上是关于您将如何在 Ruby 中设计这样的 DSL?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 django rest 框架中设计 ArrayField?

如何复制故事板中设计的 UIView?

如何在android xml中设计4个可点击的圆形字段

如何在 Flutter 的 GridView 中设计不同大小的网格?

如何在 SQL Server 数据库中设计用户/角色架构?

如何在没有 pod 的情况下在 iOS 中设计概述的文本字段