2013-05-26 35 views
0

爲了實現類似DSL的屬性分配,使用了兩用存取器。但是,我正在尋找一種重構明顯代碼重複的方法。使用define_method的兩用存取器代碼重構

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

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