使用define_method的双用途访问器代码重构器

时间:2013-05-26 10:57:32

标签: ruby methods

为了实现类似于DSL的属性分配,使用了双用途访问器。但是,我正在寻找一种方法来重构明显的代码重复。

class Layer

   def size(size=nil)
     return @size unless size 
     @size = size
   end

   def type(type=nil)
     return @type unless type 
     @type = type
   end

   def color(color=nil)
     return @color unless color 
     @color = color
   end

end

我在想通过使用define_method以及其他方法获取/设置实例变量来在类方法中定义这些方法。但是,困境是如何从类方法中访问实例?

def self.createAttrMethods
     [:size,:type,:color].each do |attr|
       define_method(attr) do |arg=nil|
           #either use instance.send() or 
           #instance_variable_get/set
           #But those method are instance method !!
       end 
     end 
end 

1 个答案:

答案 0 :(得分:1)

define_method块内,self将指向当前的类实例。因此,请使用instance_variable_get

class Foo
  def self.createAttrMethods
    [:size,:type,:color].each do |attr|
      define_method(attr) do |arg = nil|
        name = "@#{attr}"
        return instance_variable_get(name) unless arg
        instance_variable_set(name, arg)      
      end
    end
  end

  createAttrMethods
end

f = Foo.new
f.size # => nil
f.size 3
f.size # => 3