访问模块类和实例方法中的类变量

时间:2017-02-01 16:50:53

标签: ruby

我有一个模块,当包含在类中时,它包含实例方法和类方法。实例方法和类方法都应该访问类变量。

module MyModule
  @@a_class_variable = "lorem ipsum"

  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def a_class_method
      @@a_class_variable << "abc"
    end
  end

  # Use it in constructor
  def initialize
    @@a_class_variable << "abc"
  end

  def an_instance_method
    @@a_class_variable << "abc"
  end
end

当我在某个类中包含MyModule时,解释器会说: NameError:未初始化的类变量@@ a_class_method在MyModule :: ClassMethods

我做错了什么?

1 个答案:

答案 0 :(得分:0)

MyModule::ClassMethods内,您不在MyModule内且无法访问@@a_class_variableHere's一个相关的问题。

使用访问器,您的代码可以正常工作:

module MyModule
  @@a_class_variable = "lorem ipsum"

  def self.a_class_variable
    @@a_class_variable
  end

  def self.included(base)
    base.extend ClassMethods
  end

  module ClassMethods
    def a_class_method
      MyModule.a_class_variable << " abc1"
    end
  end

  # Use it in constructor
  def initialize
    @@a_class_variable << " abc2"
  end

  def an_instance_method
    @@a_class_variable << " abc3"
  end
end

class MyObject
  include MyModule
end

my_object = MyObject.new
MyObject.a_class_method
p my_object.an_instance_method
#=> "lorem ipsum abc2 abc1 abc3"

正如您在评论中所指出的那样,它向公众公开了@@a_class_variable。 将方法设置为privateprotected在上面的示例中不起作用,因为ClassMethodsMyModule不相关。

它可能不是最干净的解决方案,但您可以使用send来访问私有方法:

module MyModule
  @@a_class_variable = 'lorem ipsum'

  module ClassMethods
    def a_class_method
      MyModule.send(:__a_class_variable) << ' abc1'
    end
  end

  # Use it in constructor
  def initialize
    @@a_class_variable << ' abc2'
  end

  def an_instance_method
    @@a_class_variable << ' abc3'
  end

  class << self
    def included(base)
      base.extend ClassMethods
    end

    private

    def __a_class_variable
      @@a_class_variable
    end
  end
end