红宝石dsl制作

时间:2012-06-30 16:39:39

标签: ruby dsl

我尝试编写DSL

class Warcraft 
  class << self
    def config
      unless @instance
        yield(self)
      end
      @instance ||= self
    end

    attr_accessor :name, :battle_net

    def game(&block)
      @instance ||= Game.new(&block)
    end
  end

  class Game
    class << self
      def new
        unless @instance
          yield
        end
        @instance ||= self
      end

      attr_accessor :side, :hero

      def rune_appear_every(period)
        @rune_appear_every = period
      end

    end
  end
end

Warcraft.config do |war|
  war.name = "Warcraft III"
  war.battle_net = :iccup

  war.game do |game|
    game.side = :sentinels
    game.hero = "Furion"
    game.rune_appear_every 2.minutes
  end
end

我得到了这样的错误:

dsl.rb:41:in `block (2 levels) in <main>': undefined method `side=' for nil:NilClass (NoMethodError)

1 个答案:

答案 0 :(得分:3)

问题在于:

  def new
    unless @instance
      yield
    end
    @instance ||= self
  end

当你yield之后,当你打电话时,你没有传递任何争论:

 war.game do |game|

game变量为零。因此,不要只执行yield,而是执行yield self