定义特定的attr_accessor方法以区分几种类型的实例变量

时间:2015-05-27 16:11:21

标签: ruby metaprogramming

在描述类时,我希望能够使用专用的类方法来区分不同类型的实例变量(让我们称之为my_attrs_1,my_attrs_2)。类似的东西:

class DesignUnit
  attrs_1 :a,:b
  attrs_2 :c  
end

这样我就可以迭代这些不同的实例变量:

du=DesignUnit.new
#...
du.attrs_1.each do ...
   #I get a, and b
end

我的出发点是看看如何自定义attr_acessor定义(例如this),但我没有成功使其工作。

1 个答案:

答案 0 :(得分:0)

你是说这样的意思吗?

module CustomAttributeCollector
  def self.included(base)
    base.extend(ClassMethods)
  end
  module ClassMethods
    def attrs_1(*args)
      @_attrs_1 ||= []
      (args - @_attrs_1).each do |arg|
        attr_accessor arg
        @_attrs_1 << arg
      end
    end
    def attrs_2(*args)
      @_attrs_2 ||= []
      (args - @_attrs_2).each do |arg|
        attr_accessor arg
        @_attrs_2 << arg
      end    
    end
  end
  def attrs_1 
    self.class.instance_variable_get("@_attrs_1")
  end
  def attrs_2
    self.class.instance_variable_get("@_attrs_2")
  end 
end     

class DesignUnit
 include CustomAttributeCollector
  attrs_1 :a,:b
  attrs_2 :c
end

然后

du = DesignUnit.new
du.attrs_1
#=> [:a,:b]
du.attrs_2
#=> [:c]
du.methods.sort - Object.methods
#=> [:a, :a=, :attrs_1, :attrs_2, :b, :b=, :c, :c=]

显然,这可以清楚地使用一些清理和重构,但我认为它可以实现你的目标。