Ruby的attr_accessor如何产生类变量或类实例变量而不是实例变量?

29

如果我有一个使用attr_accessor的类,它默认会创建一个与相应getter和setter对应的实例变量。但是除了创建实例变量之外,是否有方法可以让它创建类变量或类实例变量呢?


通过"Seeing Metaclasses Clearly",逐步了解Ruby的类和对象工作方式是非常有帮助的。 - Martin DeMello
2个回答

46
就像这样:
class TYourClass
  class << self
    attr_accessor :class_instance_variable
  end
end
您可以将其视为打开类的元类(其中类本身是一个实例)并向其添加属性。 attr_accessor是Class类的方法,它向类中添加了两个方法,一个用于读取实例变量,另一个用于设置实例变量。以下是可能的实现方式:
class Class
  def my_attr_accessor(name)
    define_method name do
      instance_variable_get "@#{name}"
    end 
    define_method "#{name}=" do |new_val|
      instance_variable_set "@#{name}", new_val
    end
  end
end

完全未经测试的类属性访问器:

class Class
  def class_attr_accessor(name)
    define_method name do
      class_variable_get "@@#{name}"
    end 
    define_method "#{name}=" do |new_val|
      class_variable_set "@@#{name}", new_val
    end
  end
end

谢谢。我喜欢你说的那种方式,它打开了类的元类并添加了一个附录。但是为什么它会产生一个类实例变量而不是类变量呢?是否可能使其也产生类变量,或者这种语法只适用于类实例变量? - pez_dispenser
不同了,再看一遍答案。 - krusty.ar
这仅适用于类实例变量,因为attr_*为某个对象的实例变量定义方法。 - rampion
1
在 instance_variable_set 和 class_variable_set 的参数之间缺少一些“,”,但是这个修改太小了无法提交。 - Michael

21
在Rails项目中(或者任何使用了require 'active_support'的地方),你可以使用cattr_accessor :name来访问类变量。
虽然其他人指出的类实例变量更加有用,但是cattr_accessor函数也有其使用场景。在APIdock的cattr_accessor页面上有一些有用的讨论,可以澄清何时应该选择哪一个,同时也提供了cattr_accessorcattr_readercattr_writer函数的源码。

非常容易 - 不知道Rails提供了这个。谢谢! - Brian Armstrong

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接