2013-10-28 154 views
0

我想在一个单独的方法或常量中定义一个类属性列表,所以我可以在我的代码中多次使用这个列表。 一)很难检索attr_accessor调用(一堆getter和setter方法)的结果属性的列表;:用父类的子方法调用attr_accessor

attr_accessor :a, :b, :c 

,因为不这样做的工作和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的方法。我可以做到这一点,而不是摆脱核心Class

有没有什么办法从父级调用attr_accessor与子类'方法?

回答

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=, ... 
+0

太棒了!正是我想要的。谢谢塞尔吉奥! – Hnatt

+0

等一下,这个解决方案有什么不好?我们有什么选择? – Hnatt

+0

也许而不是初始化程序,行'attr_accessor * field_names'可能会移到B,紧跟在FIELDS行之后?这样每个子类只会定义访问器一次,它仍然会使用子类特定的字段? –