我正在尝试为包含模块的类进行类似DSL的配置,但是为类和实例方法提供配置的变量似乎需要使用访问方法乱丢模块。有更优雅的方式吗?
module DogMixin
class << self
def included(base)
base.extend ClassMethods
end
end
module ClassMethods
def breed(value)
@dog_breed = value
end
def dog_breed
@dog_breed
end
end
end
class Foo
include DogMixin
breed :havanese
end
puts Foo.dog_breed
# not implemented but should be able to do this as well
f = Foo.new
f.dog_breed
答案 0 :(得分:1)
我认为你的例子有点奇怪:) 无论如何,避免编写访问器的一种方法(赋值 - 访问器在我看来是有问题的 - 特别是在给定的例子中)是定义常量,如下例所示。但是,如果你需要运行时分配,请编辑你的问题(从而使这个答案无效:)除了你想搞乱运行时常量赋值,这可能是混乱的。)
module DogMixin
# **include** DogMixin to get `Class.dog_breed`
class << self
def included(base)
def base.dog_breed
self::DOG_BREED || "pug"
end
end
end
# **extend** DogMixin to get `instance.dog_breed`
def dog_breed
self.class.const_get(:DOG_BREED) || "pug"
end
end
class Foomer
DOG_BREED = 'foomer'
extend DogMixin
include DogMixin
end
f = Foomer.new
puts Foomer.dog_breed
puts f.dog_breed
# If I understand you correctly, this is the most important (?):
f.dog_breed == Foomer.dog_breed #=> true
需要一些(In Ruby) allowing mixed-in class methods access to class constants读取才能从模块中获取实例和类常量查找,但它可以正常工作。我不确定我是否真的喜欢这个解决方案。好问题,虽然你可以添加一些细节。