9

我正在使用 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顺便说一句:我想让它在内部@my_module_class“可见”MyModule ,因为它仅用于该模块)?是否有一些关于如何处理我试图在included do ... end上述代码块中实例化的情况的“高级”示例或教程?你有什么建议?

4

1 回答 1

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,但是您应该在源代码中添加注释,告诉人们不要这样做,并且不要宣传哈希存在。

于 2012-10-18T15:14:57.017 回答