2013-07-28 8 views
10

मैं तकनीकी चित्रों (svg/ruby) के समाधान पर काम कर रहा हूं। मैं आयतों में हेरफेर करना चाहते हैं और इस वर्ग में एक add! विधि है:रूबी में एक गहरी प्रति विधि क्यों नहीं है?

def add(delta) 
    r=self.dup/clone/"copy" # <-- not realy the 3 and no quotes, just in text here 
    r.add! delta 
end 

dup और clone नहीं है:

class Rect 
    def add!(delta) 
    @x1+=delta 
    ... # and so on 
    self 
    end 
end 

मैं भी एक Rect लौटने, लेकिन self से छेड़छाड़ नहीं एक add विधि की जरूरत है मेरी बात करें लेकिन:

def copy; Marshal.load(Marshal.dump(self)); end 

करता है।

सादे रूबी में ऐसी बुनियादी कार्यक्षमता क्यों मौजूद नहीं है? कृपया मुझे यह न बताएं कि मैं add और add! को रिवर्स कर सकता हूं, add नौकरी कर रहा हूं, और add! इसे कॉल कर रहा हूं।

+7

कॉपी करने का सबसे तेज़ तरीका है क्यों यह अस्तित्व में नहीं है? यह करता है: 'मार्शल डंप' + 'मार्शल.लोड'। क्या आप कुछ प्रोग्रामिंग भाषाओं का नाम दे सकते हैं जिनके पास भाषा स्तर पर गहरी प्रतिलिपि है? –

+0

आपका मुद्दा, मुझे लगता है कि, मैं रूबी के साथ एक खराब बच्चे की तरह हूं, यहां सब कुछ ढूंढ रहा हूं, कि मैं अन्य स्थानों पर चूक गया :- – halfbit

+0

"क्यों" यह सवाल Matz, et al के अलावा किसी अन्य के लिए कठिन/असंभव बनाता है। जवाब देने के लिए। –

उत्तर

5

मुझे यकीन नहीं है कि रूबी में कोई गहरी प्रति विधि क्यों नहीं है, लेकिन मैं जो जानकारी प्राप्त कर सकता हूं उसके आधार पर एक शिक्षित अनुमान लगाने की कोशिश करूंगा (लाइन के नीचे लिंक और उद्धरण देखें)।

इस जानकारी से निर्णय लेते हुए, मैं केवल यह अनुमान लगा सकता हूं कि रूबी की गहरी प्रति विधि नहीं है क्योंकि यह बहुत ही कम आवश्यक है और, कुछ मामलों में जहां यह वास्तव में जरूरी है, वहां अन्य, अपेक्षाकृत सरल तरीके हैं एक ही कार्य को पूरा करें:

जैसा कि आप पहले ही जानते हैं, Marshal.dump और Marshal.load का उपयोग करके वर्तमान में ऐसा करने का अनुशंसित तरीका है। यह प्रोग्रामिंग रूबी द्वारा अनुशंसित दृष्टिकोण भी है (नीचे उद्धरण देखें)।

वैकल्पिक रूप से, इन रत्नों में कम से कम 3 उपलब्ध कार्यान्वयन पाए जाते हैं: deep_cloneable, deep_clone और ruby_deep_clone; पहला सबसे लोकप्रिय है।


संबंधित सूचना

यहाँ a discussion over at comp.lang.ruby जो इस पर कुछ प्रकाश डाला सकता है। कुछ संबंधित चर्चाओं के साथ another answer here है, लेकिन यह सब Marshal का उपयोग करने के लिए वापस आता है।

Programming Ruby में गहरी प्रतिलिपि का कोई उल्लेख नहीं था, लेकिन The Ruby Programming Language में कुछ उल्लेख थे। यहाँ कुछ संबंधित अंश इस प्रकार हैं:

[...]

Marshal.dump और Marshal.load के लिए एक अन्य प्रयोग गहरी प्रतियां वस्तुओं की बनाने के लिए है:

def deepcopy(o) 
    Marshal.load(Marshal.dump(o)) 
end 

[...]

... Marshal.dump और Marshal.load द्वारा उपयोग किया जाने वाला बाइनरी प्रारूप संस्करण-निर्भर है, और नए संस्करण ओ एफ रूबी रूबी के पुराने संस्करणों द्वारा लिखी गई मार्शल वाली वस्तुओं को पढ़ने में सक्षम होने की गारंटी नहीं है।

[...]

ध्यान दें कि फ़ाइलें और मैं/हे धाराओं, साथ ही विधि और वस्तुओं बाइंडिंग भी गतिशील मार्शल किया जा रहे हैं; उनके राज्य को बहाल करने के लिए कोई विश्वसनीय तरीका नहीं होगा।

[...]

इसके बजाय सरणी के एक रक्षात्मक गहरी प्रतिलिपि बनाने के

, बस उस पर to_enum कहते हैं, और सरणी खुद के बजाय जिसके परिणामस्वरूप प्रगणक गुजरती हैं। असल में, आप अपनी सरणी के लिए एक गणनीय लेकिन अपरिवर्तनीय प्रॉक्सी ऑब्जेक्ट बना रहे हैं।

+2

यह एक उत्तर से अधिक है; मेरा निष्कर्ष - चिंता में अपने लिंक लेना - यह है कि, (गहरी) किसी ऑब्जेक्ट की प्रतिलिपि बनाना एक खराब डिजाइन के लिए सूचक (अधिक या कम अक्सर) होता है। – halfbit

+0

to_enum का उपयोग करने के बारे में अंतिम बिंदु के बारे में। मैंने कोशिश की लेकिन यह उम्मीद के अनुसार काम नहीं कर रहा है। मैं रूबी 2.2.0 ए = [1,2,3,4] => [1, 2, 3, 4] b = a.to_enum => # <गणक: [1, 2, 3, 4]: प्रत्येक> एक << 5 => [1, 2, 3, 4, 5] बी => # <गणक: [1, 2, 3, 4, 5]: प्रत्येक> कैसे बना रहा है सरणी के लिए एक अपरिवर्तनीय पॉक्सी वस्तु बनाम गणना? – RubyMiner

1

marshalling भूल जाओ। Deep_dive मणि आपकी समस्याओं को हल करेगा।

new_item = Item.new(old_item.attributes) 
new_item.save! 

यह मुद्दों के बिना नया एक के लिए आइटम मौजूदा से सभी विशेषताओं, कॉपी जाएगा:

https://rubygems.org/gems/deep_dive

0

आप कुछ इस तरह का प्रयोग क्यों नहीं कर सकते। यदि आपके पास अन्य ऑब्जेक्ट्स हैं, तो आप उन्हें अलग-अलग कॉपी कर सकते हैं।

मुझे लगता है कि यह ऑब्जेक्ट

+0

यदि आप ActiveRecord प्रकार ऑब्जेक्ट्स से निपट रहे हैं, तो शायद यह काम करेगा। लेकिन यह स्पष्ट रूप से किसी भी रूबी वस्तु के लिए काम नहीं करेगा। – flajann

संबंधित मुद्दे