直接和通过include定义嵌套类

假设我正在为我的家庭存储系统建模。 我有一堆不同类型的Container ,我发现它们中有很多都有装饰品,我已经为这种常见情况设置了一些辅助代码。

我的容器中有我的Mantlepiece和我的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 ; 但是BookcaseThings声明意味着Bookcase::Things只会嵌套HardbackPaperbackBookcase::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 ,它会跳过创建并添加到创建的模块中( false确保我们只在当前类中查找Things )。