[英]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. 将方法设置为private
或protected
在上面的示例中不起作用,因为ClassMethods
和MyModule
不相关。
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.