我有一个模块,当包含在类中时,它包含实例方法和类方法。实例方法和类方法都应该访问类变量。
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
我做错了什么?
答案 0 :(得分:0)
在MyModule::ClassMethods
内,您不在MyModule
内且无法访问@@a_class_variable
。 Here'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
。
将方法设置为private
或protected
在上面的示例中不起作用,因为ClassMethods
和MyModule
不相关。
它可能不是最干净的解决方案,但您可以使用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