2012-05-25 54 views
1

我試圖幹起一種方法,我需要在三個不同的屬性上執行相同的任務。就像這樣:通過字符串引用對象屬性

if [email protected]? 
    picture_copy = Picture.new 
    picture_copy.save! 
    item_copy.picture = picture_copy 
end 

if [email protected]_for_x.blank? 
    picture_for_x_copy = PictureForX.new 
    picture_for_x_copy.save! 
    item_copy.picture_for_x = picture_for_x_copy 
end 

if [email protected]_for_y.blank? 
    picture_for_y_copy = PictureForY.new 
    picture_for_y_copy.save! 
    item_copy.picture_for_y = picture_for_y_copy 
end 

所以基本上我運行相同的代碼,但不同的實例化對象,然後將它們分配到不同的屬性。感覺應該有一種方法來使用反射來幹這個視圖。有沒有一種方法可以將這些屬性和對象作爲字符串傳遞給輔助方法?

由於各種原因,我不能只使用.clone或.dup:主要是因爲涉及二進制文件指針,我還需要深度拷貝。

回答

2
{ 
    picture:  Picture, 
    picture_for_x: PictureForX, 
    picture_for_y: PictureForY 
}.each do |name,klass| 
    if [email protected](name).blank? 
    copy = klass.new 
    copy.save! 
    item_copy.send("#{name}=",copy) 
    end 
end 

請記住,在Ruby中沒有屬性或屬性的外部可用,只是方法(你可以選擇不使用括號來調用,以便它看起來你所訪問的屬性,並且有時可能只是返回一個實例變量的值)。

Object#send是一種神奇的方法,它允許您根據存儲在變量中的名稱調用方法。

1
def picture_for_x_blank?(s = "") 
    s = "_for_#{s}" unless s.empty? 
    m = "picture#{s}" 

    unless @item.send(m).blank? 
    copy = Kernel::const_get(m.camelize).new 
    copy.save! 
    item_copy.send("#{m}=", copy) 
    end 
end 

picture_for_x_blank? 
picture_for_x_blank?("x") 
picture_for_x_blank?("y")