简体   繁体   English

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

[英]Access class variables in a modules class and instance methods

I have a module that contains both instance methods and class methods when included in a class. 我有一个模块,当包含在类中时,它包含实例方法和类方法。 Both instance methods and class methods shall access class variables. 实例方法和类方法都应该访问类变量。

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

When I include MyModule in some class, the interpreter says: NameError: uninitialized class variable @@a_class_method in MyModule::ClassMethods 当我在某个类中包含MyModule时,解释器说: NameError:MyModule :: ClassMethods中未初始化的类变量@@ a_class_method

What am I doing wrong? 我究竟做错了什么?

When inside MyModule::ClassMethods , you're not inside MyModule and don't have access to @@a_class_variable . MyModule::ClassMethods ,你不在MyModule里面,也没有访问@@a_class_variable Here's a related question. 这是一个相关的问题。

With an accessor, your code works fine : 使用访问器,您的代码可以正常工作:

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"

As you noted in the comments, it exposes @@a_class_variable to the public. 正如您在评论中指出的那样,它向公众公开了@@a_class_variable Setting the method as private or protected wouldn't work in the above example, since ClassMethods and MyModule aren't related. 将方法设置为privateprotected在上面的示例中不起作用,因为ClassMethodsMyModule不相关。

It might not be the cleanest solution, but you could use send to access the private method : 它可能不是最干净的解决方案,但您可以使用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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM