2011-09-20 54 views
0

我有以下問題:在Ruby中,如何知道方法是屬性訪問器?

我重命名爲特定類的所有實例方法,爲了給他們額外的行爲使用alias_method_chain。我得到的所有實例方法與下面的代碼行:

self.class.instance_methods(false) 

通過這樣做,我得到我所有的實例方法,但我也感到我使用attr_accessor/attr_reader/attr_writer定義的gettes和setter。 我需要做的是檢測從上一行代碼返回的哪些方法是訪問方法,因爲我不想重命名這些方法。

很明顯,我可以檢測到方法名是否在末尾有一個「=」,這將使它成爲一個setter,如果存在,我可以看到getter是否被定義爲,但是當有隻定義一個吸氣劑?我如何檢查?特別考慮到這些屬性在初始化之前不能用於類方法「instance_variables」?

感謝您的幫助!

+0

可以檢測是否在方法名具有「=」結尾,但這種方法可以被定義手冊。這並不意味着,它是用attr_accessor/attr_writer定義的。 – knut

回答

2

您可以擴展attr_reader ...來存儲方法。

class Object 
    class << self 
    attr_reader :accessors 
    attr_reader :setters 
    attr_reader :getters 

    alias :attr_accessor_old :attr_accessor 
    def attr_accessor(methname) 
     (@accessors ||= []) << methname 
     attr_accessor_old methname 
    end 

    alias :attr_writer_old :attr_writer 
    def attr_writer(methname) 
     (@setters ||= []) << "#{methname}=".to_sym 
     attr_writer_old methname 
    end 

    alias :attr_reader_old :attr_reader 
    def attr_reader(methname) 
     (@getters ||= []) << methname 
     attr_reader_old methname 
    end 

    end 
end 

class Test 
    attr_accessor :acc 
    attr_reader :read 
    attr_writer :write 
end 
Test.instance_methods(false).each{|meth| 
    puts "#{meth} is an accessor" if Test.accessors.include?(meth) 
    puts "#{meth} is a setter" if Test.setters.include?(meth) 
    puts "#{meth} is a getter" if Test.getters.include?(meth) 
} 

結果:

acc is an accessor 
read is a getter 
write= is a setter 
+0

嘿,感謝你的想法,聽起來像一個很好的計劃,我可能會這樣做! – Deleteman

相關問題