「多套配置」是指:Cls.config_a.foo; Cls.config_b.foo?如果是这个意思,那么我粗糙地实现了一下:
# configurable.rb
module Configurable
module Enable
cattr_accessor :current_config
def method_missing(method, *args)
cattr_accessor method
define_singleton_method method do
self.current_config = method
config = instance_variable_get("@#{current_config}_config")
config.nil? ? self : config
end
send method
end
end
def self.with(*attrs)
# 使用配置属性定义匿名类
config_class = Class.new do
attr_accessor *attrs
end
# 为可混入的类方法定义匿名模块
class_methods = Module.new do
define_method :config do
config_var = "@#{current_config}_config"
instance_variable_set(config_var, config_class.new) if instance_variable_get(config_var).nil?
instance_variable_get(config_var)
end
def configure
yield config
end
end
# 创建并返回新的模块
Module.new do
singleton_class.send :define_method, :included do |host_class|
host_class.extend class_methods
end
end
end
end
# my_config.rb
class MyConfig
extend Configurable::Enable
include Configurable.with :foo
end
# Usage
MyConfig.config_a.configure do |config|
config.foo = 'bar'
end
MyConfig.config_b.configure do |config|
config.foo = 'foo'
end
puts MyConfig.config_a.foo
puts MyConfig.config_b.foo