2011-09-20 59 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

相关问题