我有一个基本模块,里面有一些逻辑,它包含在各种类中。现在我需要一个configure
块来设置类的行为方式。
我尝试了以下代码:
class MyConfig
attr_accessor :foo, :bar
end
module BaseModule
def self.included base
base.include InstanceMethods
base.extend ClassMethods
end
module ClassMethods
attr_reader :config
def configure &block
@config = MyConfig.new
block.call(@config)
end
end
module InstanceMethods
def do_something
puts self.class.config.inspect
end
end
end
class MyClass1
include BaseModule
configure do |config|
config.foo = "foo"
end
end
class MyClass2
include BaseModule
configure do |config|
config.bar = "bar"
end
end
MyClass1.new.do_something
#<MyConfig:0x007fa052877ea0 @foo="foo">
MyClass2.new.do_something
#<MyConfig:0x007fa052877ce8 @bar="bar">
- 我不确定模块/类的实例变量
@config
是否是配置类的最佳方法。这是正确的方法,还是有更好的解决方案?- 当模块仅包含在
醇>base.extend ClassMethods
中时,是否也可以使用include BaseModule
?开发人员可以期望只包含实例方法,但作为副作用,还有扩展的类方法。
更新
我添加了一个MyConfig
类,从中创建了一个新实例。这样做的好处是可以使用config.foo = "foo"
。
答案 0 :(得分:0)
我已经改变了你的代码,使用了我和很多流行的宝石(比如设计)用于配置的方法。希望你会喜欢它:))
module BaseModule
def self.included base
base.include InstanceMethods
base.extend ClassMethods
end
module ClassMethods
mattr_accessor :foo
@@foo = 'initial value'
def configure &block
block.call(self)
end
end
module InstanceMethods
def do_something
puts foo
end
end
end
class MyClass1
include BaseModule
configure do |klass|
klass.foo = "foo"
end
end
class MyClass2
include BaseModule
configure do |klass|
klass.foo = "bar"
end
end
MyClass1.new.do_something
# => "foo"
MyClass2.new.do_something
# => "bar"
变化是:
configure
方法返回self
,这样您就可以用简单,可读,类似于rails的方式配置您的类示例:
Kid.config do |k|
k.be_kind = false
k.munch_loudly = true
k.age = 12
end