Ruby on rails 如何向Ruby类添加简单的DSL?

Ruby on rails 如何向Ruby类添加简单的DSL?,ruby-on-rails,ruby,Ruby On Rails,Ruby,我如何实现一个类,让我向DSL注册其他类,并在实例化后访问它们,如下面的示例所示: module Google class Search def self.run puts :search end end class Map def self.run puts :map end end class Calendar def self.run puts :calendar end

我如何实现一个类,让我向DSL注册其他类,并在实例化后访问它们,如下面的示例所示:

module Google
  class Search
    def self.run 
      puts :search
    end
  end

  class Map
    def self.run 
      puts :map
    end
  end

  class Calendar
    def self.run 
      puts :calendar
    end
  end
end

class One
  has Google::Search
  has Google::Map

  def perform
    # run through all registered classes, instantiate and then call run on each
  end
end

class Two
  has Google::Calendar

  def perform
    # run through all registered classes, instantiate and then call run on each
  end
end

One.new.peform 
# => 'search'
# => 'map'

One.new.peform 
# => 'calendar'

您的初始代码包含几个错误,它甚至无法通过ruby解释器

首先,您需要实现DSL处理程序:

module DSLHandler
  @@classes = {}
  def classes
    @@classes[self.name] ||= []
  end
  def has clazz
    classes << clazz
    puts "registered #{clazz} in #{classes}"
  end
  extend self
end
结果如预期:

# ⇒ registered Google::Search in [Google::Search]
# ⇒ registered Google::Map in [Google::Search, Google::Map]
# ⇒ search
# ⇒ map

可以将DSL实现为基类或mixin。你有明确的目标吗?你试过实施什么吗?你的代码很好地解释了这个问题,但它有点空壳,所以现在还不清楚您对如何开始编写DSL知道多少。ruby中的嵌套类也称为内部类。@NielSalter如何实现它,以便第二个类可以拥有自己的包含类列表classes@NeilSlater我再也不会在早上喝咖啡之前回答这么多问题了。重复3次。更新了答案。@NeilSalter。当我测试你的解决方案时,我没有得到预期的结果。它仍然没有处理单独的类。我已经更新了我的问题,可能help@Roman哈希键实现中出现错误。在类级别运行此代码时,存在
@@classes[self.class.name]
。因此应该有
@@classes[self.name]
self.class
是class,而
self
class
class的一个实例。)我已经更新了一个答案,现在它工作得很好。
# ⇒ registered Google::Search in [Google::Search]
# ⇒ registered Google::Map in [Google::Search, Google::Map]
# ⇒ search
# ⇒ map