您将如何在 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?