Getter/Setter for class variables in Ruby
对于使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | class School @@syllabus = :cbse def self.syllabus @@syllabus end def self.syllabus=(_) @@syllabus = _ end end School.syllabus = :icse School.syllabus # => :icse |
您需要做的只是在类的范围内声明
1 2 3 4 5 6 7 8 | class School class << self attr_accessor :syllabus end end School.syllabus = :icse School.syllabus # => :icse |
请注意,虽然底层成员不是
The issue with class variables is inheritance. Let’s say I want to subclass Polygon with Triangle like so:
1
2
3
4
5
6 class Triangle < Polygon
@@sides = 3
end
puts Triangle.sides # => 3
puts Polygon.sides # => 3Wha? But Polygon’s sides was set to 10? When you set a class variable, you set it for the superclass and all of the subclasses.
UriAgassi的答案是在类本身上设置实例变量,类似于类变量,但与类变量不同。看到类变量和类实例变量之间的区别了吗?为了解释这些差异。
你要找的是像Rails的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | 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 |
然后像这样使用:
1 2 3 4 5 | class School extend CattrAccessors attr_accessor :syllabus end |
我没有测试过上面的模块,所以它可能不工作。如果没有,请告诉我。