如何实现一个允许我使用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'
答案 0 :(得分:5)
您的初始代码包含多个错误,甚至不会通过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
现在需要了解,因为在类级别调用has
,所以在同一级别上执行必须。总结:
class Google ; end
class Google::Search
def self.run
puts :search
end
end
class Google::Map
def self.run
puts :map
end
end
class Google
extend DSLHandler
has Google::Search
has Google::Map
def self.perform
classes.each { |clazz| clazz.run }
end
end
Google.perform
结果如预期:
# ⇒ registered Google::Search in [Google::Search]
# ⇒ registered Google::Map in [Google::Search, Google::Map]
# ⇒ search
# ⇒ map