我应该在`included do ... end`块中包含哪些内容?

时间:2012-10-18 15:02:34

标签: ruby-on-rails ruby ruby-on-rails-3 module activesupport

我正在使用Ruby on Rails 3.2.2。我正在实现一个模块,并使用RoR ActiveSupport::Concern功能将其包含在我的课程中。它使included do ... end块生成代码可以在包含模块的类的类上下文中执行。

我的疑问是:我应该包含在included do ... end块中?例如,它是“普通”/“好” “练习以下内容?

module MyModule
  extend ActiveSupport::Concern

  class MyModuleClass
    attr_accessor :attr1, :attr2, :attr3

    def initialize(attrs)
     @attr1 = attrs[:attr1]
     @attr2 = attrs[:attr2]
     @attr3 = attrs[:attr3]
    end
  end

  included do
    @my_module_class = MyModuleClass.new(some_attrs)
  end
end

更多@my_module_class变量可用作MyModule的包含类中的属性( BTW :我想制作@my_module_class仅在MyModule内部为“可见” ,因为它仅用于该模块)?是否有一些“高级”示例或教程如何处理我试图在上面代码的included do ... end块中实例化的情况?你有什么建议?

1 个答案:

答案 0 :(得分:2)

@my_class将是MyClass的一个实例,而不是MyModule。如果你想让MyClass的所有实例成为MyModule的一个实例,你应该写:

 include MyModule

在类定义中。

我认为如果你在编辑之前查看这个问题的原始版本,我的答案是有道理的。

编辑1:

让我们添加您的示例,并说您有一个名为Foo的类:

class Foo
    include MyModule
end

你想创建一个与Foo相关的MyModuleClass实例,但听起来你真的不想修改Foo或让它访问MyModuleClass。我建议你使用哈希表:

module MyModule
    # ...

    @hash = {}
    class << self
        attr_accessor :hash
    end

    included do
        MyModule.hash[self] = MyModuleClass.new(some_attrs)
    end
end

我认为这样可行,并且它避免了向Foo类对象添加实例变量。从技术上讲,ruby代码的任何部分都可以访问MyModule.hash,但你应该在源代码中添加注释,告诉人们不要这样做,并且不要宣传哈希存在。