2009-10-09 15 views
22

संभव डुप्लिकेट:
What's the best way to make a deep copy of a data structure in Perl?पर्ल में हैश के हैश की गहरी प्रतिलिपि बनाने का सबसे अच्छा तरीका क्या है?

इससे पहले कि मैं यह अपने आप कोडिंग और पहिया पुनर्रचना शुरू, तुम कैसे hashrefs डुप्लिकेट के बिना हैश के हैश कॉपी करूं?

मैं Config::General के माध्यम से हैश के हैश का हैश पढ़ रहा हूं। यानी, डेटा संरचना है:

my %config = (group => { item1 => { foo => 'value', 
            bar => 'value', 
            }, 
          item2 => { foo => 'value', 
            bar => 'value', 
            }, 
          item3 => { foo => 'value', 
            bar => 'value', 
            }, 
         }, 
      ); 

मैं तो यह अपसंदर्भन द्वारा config से अपने समूह खींच और कॉन्फ़िग फ़ाइल को फिर से लिखने से पहले क्रम पर सामग्री को बदलें:

my %group = %{$config{'group'}}; 

समस्या मुझे लगता है कि है यह देखने के लिए जांचें कि क्या परिवर्तन किए गए हैं और सिस्टम की फ़ाइल संरचना में संबंधित परिवर्तन करते हैं। मैं जाँच करके ऐसा नहीं कर सकते:

if ($group{'item1'}{'foo'} ne $config{'group'}{'item1'}{'foo'}) { 
    ### Stuff! 
} 

$group{'item1'} के रूप में और $config{'group'}{'item1'} दोनों में ठीक उसी hashref हैं।

अब कॉन्फ़िगरेशन फ़ाइल को फिर से पार्स करने के लिए यह छोटा होना चाहिए, और डिस्क पर सहेजने से पहले संपादित संस्करण के विरुद्ध डिस्क से पार्स की गई प्रतिलिपि की तुलना करें, मुझे यकीन है कि एक नेस्टेड ड्रेफरेंस के लिए एक तरीका है एक जटिल डेटा संरचना, हैश रेफ की सामग्री की प्रतिलिपि बनाना और न केवल संदर्भों की प्रतिलिपि बनाना। सीपीएएन पर एक सरसरी परीक्षा कुछ भी नहीं बदलती है। मैं क्या खो रहा हूँ?

#!/usr/bin/perl 

use Benchmark qw(:all) ; 
use Storable qw(dclone); 
use Clone qw(clone); 

my %config = (group => { item1 => { foo => 'value', 
            bar => 'value', 
            }, 
          item2 => { foo => 'value', 
            bar => 'value', 
            }, 
          item3 => { foo => 'value', 
            bar => 'value', 
            }, 
         }, 
      ); 

my $ref = $config{'group'}; 

timethese(100000, { 
    'Clone' => sub { my %group = %{ clone $ref }}, 
    'Storable' => sub { my %group = %{ dclone $ref }}, 
}); 

परिणामों में:

बेंचमार्क

मेरा उत्तर मिल गया

 
Benchmark: timing 100000 iterations of Clone, Storable... 
    Clone: 2 wallclock secs (2.26 usr + 0.01 sys = 2.27 CPU) @ 44052.86/s (n=100000) 
Storable: 5 wallclock secs (4.71 usr + 0.02 sys = 4.73 CPU) @ 21141.65/s (n=100000) 
+2

यदि आप कहते हैं, तो आपको अपना जवाब मिल गया है, आपको उस पोस्ट को देखना चाहिए जिसने आपके प्रश्न का सही उत्तर के रूप में उत्तर दिया है। –

उत्तर

-3

हमेशा Storable या डाटा :: डम्पर के माध्यम से हैश स्टोर कर सकते हैं, और पुन: सौंपा संग्रहीत मूल्य एक नए हैश में। संदर्भित लिंक बनाए रखने के बिना इसे पूर्ण प्रति प्राप्त करनी चाहिए।

use Storable; 
my $serialized = freeze \%config; 
my %newconfig = %{ thaw($serialized) }; 
+3

इस मामले के लिए विशेष कार्य 'डॉकोन' है –

29
Storable :: dclone प्रलेखन मैं Clone पाया से

:

my $copy = clone (\@array); 

# or 

my %copy = %{ clone (\%hash) }; 

लचीलेपन की जरूरत नहीं है, और Storable::dclone तुलना में तेजी से होने का दावा।

+2

बेंचमार्क दिखाता है कि यह लगभग दोगुनी है जितना तेज़ है – Oesor

+0

ऐसा लगता है कि यह क्लोन थ्रेड्स :: साझा डेटा strucutre नहीं है? पैकेज "थ्रेड्स :: साझा :: टाई" – ealeon

7

दीप डेटा संरचना 101:

  • उपयोग Storable के dclone एक संरचना की गहरी प्रतिलिपि बनाने के लिए, और freeze और thaw क्रमानुसार करने/भंडारण के लिए उन्हें deserialize (एक डेटाबेस में कहते हैं, या एक http कुकी (लेकिन आपको उपयोगकर्ता को जो भी भेजना मुश्किल हो, उसे एन्क्रिप्ट करना चाहिए)।
  • दो गहरी डेटा संरचनाओं की तुलना करने के लिए Data::Compare (या Test::Deep या Test::Differences एक इकाई परीक्षण के अंदर) का उपयोग करें।
  • अपनी ऑब्जेक्ट्स की तरह दिखने के लिए डिबगिंग में Data::Dumper या Data::Dump का उपयोग करें। लेकिन किसी अन्य ऑब्जेक्ट के आंतरिक के साथ छेड़छाड़ करने के लिए लाइसेंस के रूप में इसका उपयोग न करें; एपीआई का प्रयोग करें। :)
+1

डेटा के माध्यम से ऑब्जेक्ट विधि "FETCH" का पता नहीं लगा सकता है :: डेटा की तुलना करें मेरे साथ तुलना करें, मैं अभी भी अपने हैंश को अनदेखा कर रहा हूं। मैं वास्तव में जटिल सामग्री की तुलना करने के लिए कुछ समय कोशिश करूँगा; धन्यवाद – Oesor

+1

टेस्ट :: दीप, और टेस्ट :: सर्वव्यापी टेस्ट की वजह से अंतर पक्षपात से बाहर हो रहे हैं :: अधिक की नई is_deeply कार्यक्षमता - इसे जांचें। उपयोग करने के लिए आसान गंदगी, और आपको एक सुंदर त्रुटि मिलती है। –

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

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