使用来自父类的子方法调用attr_accessor

时间:2013-10-28 12:57:52

标签: ruby inheritance

我想在单独的方法或常量中定义类属性列表,因此我可以在代码中多次使用该列表。

attr_accessor :a, :b, :c

不能完成这项工作,因为: a)很难从attr_accessor调用(一堆setter和getter)的结果中检索属性列表;和 b)我需要在我的属性列表中放入一些元数据。将列表移动到常量可以完成工作,因为现在我可以使用列表执行我想要的操作,并仍然将符号数组传递给attr_accessor。 E.g:

class A
  FIELDS = {a:'field a', b:'field b'}

  def self.field_names
    FIELDS.keys
  end

  attr_accessor *field_names
end

但我想在很多类似的类中执行此操作,因此要保持干燥,我必须将所有重复的代码(如self.field_namesattr_accessor *field_names移动到父类。但这不起作用:

class A
  FIELDS = {a:'field a', b:'field b'}

  def self.field_names
    FIELDS.keys
  end

  attr_accessor *field_names
end

class B < A
  FIELDS = {c: 'field c'}
end

因为attr_accessor仍然接收A的方法。我可以在不摆弄核心Class的情况下这样做吗?

有没有办法从父级调用带有子类'方法的attr_accessor?

1 个答案:

答案 0 :(得分:2)

您的代码无法运行,因为attr_accessor在加载类A时仍然不可避免地被调用。此时,类B尚未(完全)存在,因此它无法改变常量。

例如,您可以推迟创建实例方法,直到创建实际实例(我不太喜欢这个解决方案)。

class A
  FIELDS = {a:'field a', b:'field b'}

  def initialize
    self.class.class_eval do
      attr_accessor *field_names
    end
  end

  def self.field_names
    self.const_get(:FIELDS).keys
  end

end

class B < A
  FIELDS = {c: 'field c'}
end

b = B.new
b.methods() # => [:c, :c=, ...