0

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

attr_accessor :a, :b, :c

没有完成这项工作,因为:a)很难从attr_accessor调用结果(一堆setter和getter)中检索属性列表;b)我需要在我的属性列表中添加一些元数据。将列表移动到一个常量就可以了,因为现在我可以对列表做我想做的事情,并且仍然将一个符号数组传递给attr_accessor. 例如:

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 的方法。我可以在不摆弄 core 的情况下做到这一点Class吗?

有什么方法可以从父级调用 attr_accessor 与子类的方法?

4

1 回答 1

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=, ...
于 2013-10-28T13:07:07.370 回答