perl

2011-12-12 12 views
9

में संदर्भ द्वारा हैश को कैसे पास किया जाए, मुझे पता है कि यह आसानी से Google पर खोजने योग्य होना चाहिए, पेर्ल के एक छोटे से उपयोग का उल्लेख न करें, लेकिन मैंने कई समाधानों को आजमाया है और अब तक उनमें से कोई भी नहीं देता है अपेक्षित् व्यवहार। अनिवार्य रूप से, मैं एक सबराउटिन को कॉल करने की कोशिश कर रहा हूं, उस सबराउटिन से हैश का संदर्भ लौटाता हूं, उस हैश को किसी अन्य सबराउटिन के संदर्भ में पास करता हूं, और फिर उस हैश की सामग्री को निम्न के जैसा कोड के माध्यम से प्रिंट करता है:perl

#!/usr/bin/perl                                                 

my $foo = make_foo(); 

foreach $key (sort keys %$foo) { 
    print "2 $key $$foo{$key}\n"; 
} 

print_foo(\%foo); 

sub print_foo 
{ 
    my %loc = ???; 
    foreach $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

sub make_foo 
{ 
    my %ret; 
    $ret{"a"} = "apple"; 
    foreach $key (sort keys %ret) { 
     print "1 $key $ret{$key}\n"; 
    } 
    return \%ret; 
} 

क्या कोई मुझे हैश की अतिरिक्त प्रति बनाये बिना (सबराउटिन के माध्यम से) करने का सबसे अच्छा तरीका बता सकता है? मैंने जिन समाधानों का प्रयास किया है, उन्होंने "3" से शुरू होने वाली किसी भी पंक्ति को मुद्रित नहीं किया है।

+8

एक तरफ, मैं दृढ़ता से अनुशंसा करता हूं कि आप अपने सभी कोड के शीर्ष पर 'सख्त उपयोग' का उपयोग शुरू करें। आपको 'my' का उपयोग करके अपने चर घोषित करने के लिए अपनी' foreach' लाइनों को बदलने की आवश्यकता होगी, लेकिन यह आपको सरल टाइपो को डिबग करने वाले कई सिरदर्दों को बचाएगा। – zostay

उत्तर

10

आप इसे भिन्नता एक संदर्भ के रूप में पैरामीटर निकालने के लिए और उसके बाद:

sub print_foo 
{ 
    my ($loc) = @_; 
    foreach my $key (sort keys %$loc) { 
     print "3 $key $loc->{$key}\n"; 
    } 
} 

जब भी आप एक संदर्भ बनाने के लिए, आप यह भिन्नता के लिए स्पष्ट रूप से। साथ ही, सावधान रहें कि संदर्भ में कोई भी परिवर्तन मूल बदल जाएगा। आप मूल को बदलने से बचना चाहते हैं, तो आप या तो एक सूची के रूप में हैश पारित कर सकते हैं:

print_foo(%foo); # flattens the hash to a list and passes it in through @_ 

sub print_foo 
{ 
    my (%loc) = @_; # load the hash from the list 
    foreach my $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

या एक नई हैश में हैश संदर्भ कॉपी:

sub print_foo 
{ 
    my ($ref_loc) = @_; # changes to %$ref_loc will change %foo 
    my %loc = %$ref_loc; # COPY, changes to %loc do not change %foo 
    foreach my $key (sort keys %loc}) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 
-1

आप एक संदर्भ से रूपांतरित होने की एक हैश के लिए इतना की तरह हैं:

my %loc = %{@_[0]}; 

या

my %loc = %{shift}; 

तुम भी एक संदर्भ के रूप में रखना कर सकते हैं:

my $locref = shift; 
foreach $key (sort keys %$locref}) { 
    print "3 $key $locref->{$key}\n"; 
} 

यह कमांड लाइन पर perldoc perlref टाइप करके जानकारी मिल सकती है।

+4

सिंगल एलिमेंट स्लाइस '% {$ _ [0]} ','% {shift}' के रूप में बेहतर लिखा गया है, 'शिफ्ट' नामक हैश वैरिएबल का जिक्र कर रहा है, तो संभवतः आप '% {+ shift}' या '% {shift @_} '। नामांकित लूप चर लेक्सिकल 'मेरी $ कुंजी का अनुमान लगाया जाना चाहिए ... ' –

+0

सभी मायने रखता है। – Dan

3

बाकी सब कुछ अच्छा है, इसलिए मैं 'सिर्फ print_foo पर ध्यान केंद्रित करने ...

sub print_foo 
{ 
    my %loc = %{shift @_}; 
    foreach $key (sort keys %loc) { 
     print "3 $key $loc{$key}\n"; 
    } 
} 

FYI करें, आप को एहसास है कि% loc अब हैश की एक प्रति है की जरूरत जा रहा हूँ (: Confusion about proper usage of dereference in Perl मैं एक सवाल जो इस यहाँ बताते पूछा)। प्रतिलिपि बनाने से बचने के लिए ...

sub print_foo 
{ 
    my $loc = shift @_; 
    foreach $key (sort keys %$loc) { 
     my $val = $loc->{$key} 
     print "3 $key $val\n"; 
    } 
}