直接和通过包含定义嵌套类

  • 本文关键字:定义 嵌套 包含 ruby
  • 更新时间 :
  • 英文 :


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

我的

容器中有我的MantlepieceBookcase。我只在前者上存放装饰品;而后者则拥有所有的装饰品,以及精装和软装书。

这是一个初步尝试:

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(。

最新更新