假设我正在为我的家庭存储系统建模。我有很多不同类型的Container
,而且我发现其中很多都有装饰品,因此我为这种常见情况设置了一些辅助代码。
我的容器中有我的Mantlepiece
and my Bookcase
。我只在前者上存放装饰品;而后者则拥有所有装饰品以及精装书和平装书。
这是初步尝试:
module Properties
def has_ornament
include OrnamentThings
end
module OrnamentThings
module Things
class Ornament
end
end
end
end
class Container
extend Properties
end
class Mantlepiece < Container
has_ornament
end
class Bookcase < Container
has_ornament
module Things
class Hardback
end
class Paperback
end
end
end
[Mantlepiece, Bookcase].each do |place|
puts place.name
puts place.constants.inspect
puts place::Things.constants.inspect
end
# Output:
# Mantlepiece
# [:Things]
# [:Ornament]
# Bookcase
# [:Things]
# [:Hardback, :Paperback]
您可以看到Mantlepiece
正确筑巢Mantlepiece::Things::Ornament
;但课堂上的声明Things
for Bookcase
意思是Bookcase::Things
仅有巢穴Hardback
and Paperback
. Bookcase::Things::Ornament
不见了。
我可以把这个写得很工整吗Bookcase
可以打电话has_ornament
,然后声明自己的一组Things
,并且它们都嵌套在同一个命名空间中吗?
即使你的壁炉架和书柜都有东西,但这些东西是不同的(因为它们包含不同的类)。所以他们不能只包括一些常见的Things
模块;相反,他们必须定义自己的单独的Things
,就像你在Bookcase
通过声明module Things
.
def has_ornament
const_set(:Things, Module.new) unless const_defined? :Things, false
self::Things.include OrnamentThings
end
module OrnamentThings
class Ornament
end
end
这是可行的,因为 Ruby 允许您使用与声明模块相同的语法重新打开模块。has_ornament
定义了一个全新的Things
模块,然后您可以打开该模块来添加更多内容。如果你打电话has_ornament
在您的自定义内容之后,它会跳过创建并添加到模块中you做了(false
确保我们正在寻找Things
仅在当前班级)。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)