【问题标题】:In Ruby, how can I know if a method is an attribute accessor?在 Ruby 中,我如何知道一个方法是否是一个属性访问器?
【发布时间】:2011-09-20 21:29:22
【问题描述】:

我有以下问题:

我正在重命名特定类的所有实例方法,使用 alias_method_chain 以赋予它们额外的行为。我使用以下代码行获取所有实例方法:

self.class.instance_methods(false)

通过这样做,我获得了所有实例方法,但我也获得了使用 attr_accessor / attr_reader / attr_writer 定义的 gettes 和 setter。 我需要做的是检测从上一行代码返回的哪些方法是访问器方法,因为我不想重命名它们。

显然,我可以检测方法名称是否在末尾有一个“=”,这将使它成为一个 setter,如果存在,我可以查看 getter 是否也被定义,但是当只有一个吸气剂定义?我该如何检查?特别考虑到类方法“instance_variables”的属性在初始化之前不可用?

感谢您的帮助!

【问题讨论】:

  • 您可以检测方法名称是否以“=”结尾,但该方法可以手动定义。不是说,是用attr_accessor/attr_writer定义的。

标签: ruby-on-rails ruby metaprogramming


【解决方案1】:

您可以扩展 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

【讨论】:

  • 嘿,谢谢你的想法,听起来是个好计划,我可能会这样做!
猜你喜欢
  • 1970-01-01
  • 2010-10-11
  • 2010-12-06
  • 2011-11-27
  • 2019-05-09
  • 1970-01-01
  • 2011-01-26
  • 1970-01-01
相关资源
最近更新 更多