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

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

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

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

【问题讨论】:

    标签: ruby-on-rails ruby 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-06
      • 2018-07-10
      • 1970-01-01
      • 2013-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多