2013-10-28 202 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行之後?這樣每個子類只會定義訪問器一次,它仍然會使用子類特定的字段? –