可以为类变量自动生成/启用getter / setter,就像使用attr_accessor
为实例变量生成的那样:
class School
@@syllabus = :cbse
def self.syllabus
@@syllabus
end
def self.syllabus=(_)
@@syllabus = _
end
end
School.syllabus = :icse
School.syllabus # => :icse
答案 0 :(得分:4)
您需要做的就是在类的范围内声明attr_accessor
:
class School
class << self
attr_accessor :syllabus
end
end
School.syllabus = :icse
School.syllabus # => :icse
请注意,虽然底层成员不会<{1}}(这些变量没有内置解决方案)但是类范围内有@@syllabus
,无论如何都是推荐的方法,请参阅this博客文章,了解两者之间的差异:
类变量的问题是继承。假设我想用Triangle子类化Polygon,如下所示:
@syllabus
什?但是Polygon的两侧是10?设置类变量时,可以为超类和所有子类设置它。
答案 1 :(得分:2)
Uri Agassi的答案是在类本身上设置实例变量,类似于类变量,但与类变量不同。有关差异的解释,请参见Difference between class variables and class instance variables?。
你正在寻找的东西就像铁轨&#39; cattr_accessor
。您可以通过一些元编程实现这一目标
module CattrAccessors
def cattr_accessor(*attrs)
cattr_reader(*attrs)
cattr_writer(*attrs)
end
def cattr_reader(*attrs)
attrs.each do |attr|
define_singleton_method(attr) { class_variable_get("@@#{attr}") }
end
end
def cattr_writer(*attrs)
attrs.each do |attr|
define_singleton_method("#{attr}=") { |value| class_variable_set("@@#{attr}", value) }
end
end
end
然后像这样使用它:
class School
extend CattrAccessors
attr_accessor :syllabus
end
我还没有测试过上面的模块,所以它可能无法正常工作。如果没有,请告诉我。