0

我尝试写 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)
4

1 回答 1

3

问题在这里:

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

yield稍后当您调用时,您没有传递任何参数:

 war.game do |game|

game变量为零。因此,与其只是做yield,不如做yield self

于 2012-06-30T16:47:15.520 回答