Getter/Setter 对于 Ruby 中的 class 个变量
Getter/Setter for class variables in Ruby
对于使用 attr_accessor
:
为实例变量生成的 class 变量,getter/setter 是否可以 auto-generated/enabled
class School
@@syllabus = :cbse
def self.syllabus
@@syllabus
end
def self.syllabus=(_)
@@syllabus = _
end
end
School.syllabus = :icse
School.syllabus # => :icse
您需要做的就是在 class 的范围内声明 attr_accessor
:
class School
class << self
attr_accessor :syllabus
end
end
School.syllabus = :icse
School.syllabus # => :icse
请注意,虽然基础成员 不会 @@syllabus
(没有针对此类变量的内置解决方案),但 @syllabus
class 范围,这是推荐的方式,请参阅 this 博客 post 了解两者之间的区别:
The issue with class variables is inheritance. Let’s say I want to subclass Polygon with Triangle like so:
class Triangle < Polygon
@@sides = 3
end
puts Triangle.sides # => 3
puts Polygon.sides # => 3
Wha? 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.
Uri Agassi 的回答是在 class 本身上设置实例变量,这与 class 变量类似但不同。有关差异的解释,请参阅 Difference between class variables and class instance variables?。
您要查找的内容类似于 rails' 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
我没有测试过上面的模块,所以它可能不工作。如果没有,请告诉我。
对于使用 attr_accessor
:
class School
@@syllabus = :cbse
def self.syllabus
@@syllabus
end
def self.syllabus=(_)
@@syllabus = _
end
end
School.syllabus = :icse
School.syllabus # => :icse
您需要做的就是在 class 的范围内声明 attr_accessor
:
class School
class << self
attr_accessor :syllabus
end
end
School.syllabus = :icse
School.syllabus # => :icse
请注意,虽然基础成员 不会 @@syllabus
(没有针对此类变量的内置解决方案),但 @syllabus
class 范围,这是推荐的方式,请参阅 this 博客 post 了解两者之间的区别:
The issue with class variables is inheritance. Let’s say I want to subclass Polygon with Triangle like so:
class Triangle < Polygon @@sides = 3 end puts Triangle.sides # => 3 puts Polygon.sides # => 3
Wha? 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.
Uri Agassi 的回答是在 class 本身上设置实例变量,这与 class 变量类似但不同。有关差异的解释,请参阅 Difference between class variables and class instance variables?。
您要查找的内容类似于 rails' 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
我没有测试过上面的模块,所以它可能不工作。如果没有,请告诉我。