2012-01-01 18 views
6

के बाद संदर्भ है मेरे पास कक्षा का ऑब्जेक्ट है, और मैं इसे dup के साथ डुप्लिकेट करना चाहता हूं। आवृत्ति चरों में से एक एक सरणी है, और ऐसा लगता है कि यह संदर्भित है। मैंने सोचा कि डुप्लिकेट ने वास्तव में एक डिप्लीकेट बनाया है। ,इंस्टेंस वैरिएबल अभी भी 'dup'

irb(main):094:0> class G 
irb(main):095:1> attr_accessor :iv 
irb(main):096:1> def initialize 
irb(main):097:2> @iv = [1,2,3] 
irb(main):098:2> end 
irb(main):099:1> end 
=> nil 

irb(main):100:0> a=G.new 
=> #<G:0x27331f8 @iv=[1, 2, 3]> 

irb(main):101:0> b=a.dup 
=> #<G:0x20e4730 @iv=[1, 2, 3]> 

irb(main):103:0> b.iv<<4 
=> [1, 2, 3, 4] 
irb(main):104:0> a 
=> #<G:0x27331f8 @iv=[1, 2, 3, 4] 

मैं a अपरिवर्तित होने की अपेक्षा करेंगे क्योंकि dup एक नया चर बनाता है, को संदर्भित नहीं:

यहाँ मेरी आईआरबी सत्र है।

यह भी ध्यान रखें कि यदि आप को G::initialize में स्केलर के साथ प्रतिस्थापित करना चाहते हैं, तो dup इसका संदर्भ नहीं देगा।

उत्तर

6

dup crates a shallow copy; उदाहरण चर द्वारा संदर्भित वस्तुओं की प्रतिलिपि नहीं बनाई गई है।

कैनोनिकल (उदाहरण के लिए, वास्तव में आसान) गहरी प्रतिलिपि हैक मार्शल/अनमशाल है, जो आपके वास्तविक उपयोगकेस में काम कर सकती है या नहीं (मान लीजिए कि यह एक सरलीकृत उदाहरण है)। यदि ऐसा नहीं होता है, या यदि मार्शलिंग अक्षम है, तो initialize_copy मार्ग एक बेहतर विकल्प है।

pry(main)> a = G.new 
=> #<G:0x9285628 @iv=[1, 2, 3]> 
pry(main)> b = a.dup 
=> #<G:0x92510a8 @iv=[1, 2, 3]> 
pry(main)> a.iv.__id__ 
=> 76819210 
pry(main)> b.iv.__id__ 
=> 76819210 
pry(main)> b = Marshal::load(Marshal.dump(a)) 
=> #<G:0x9153c3c @iv=[1, 2, 3]> 
pry(main)> a.__id__ 
=> 76819220 
pry(main)> b.__id__ 
=> 76193310 
7

dup और clone के डिफ़ॉल्ट कार्यान्वयन सिर्फ एक उथले प्रति बनाएं, ताकि आप दो वस्तुओं एक ही सरणी की चर्चा करते हुए होगा।

class G 
    attr_accessor :iv 
    def initialize_copy(source) 
    super 
    @iv = source.iv.dup 
    end 
end 

तो दो वस्तुओं दो अलग सरणियों का उल्लेख होगा: व्यवहार है कि आप चाहते हैं पाने के लिए आपको एक initialize_copy समारोह (जो dup और clone द्वारा कहा जाता है) को परिभाषित करना चाहिए। सरणियों उन में परिवर्तनशील वस्तुओं है, तो आप सरणियों में भी गहरी और dup प्रत्येक वस्तु के जाने के लिए चाहते हो सकता है:

def initialize_copy(source) 
    super 
    @iv = source.iv.collect &:dup 
end 
0

अवहेलना dup या clone विधि:

def dup 
    Marshal::load(Marshal.dump(self)) 
    end