2010-01-27 25 views
5

मैं कैसे पालन की तरह एक हैश बनाने होगा:

my %hash = (key1=>"Something", key2=>$hash{key1} . "Else"); 

इस जबकि जब मैं हैश घोषित नहीं किया जा सकता है? अब तक, केवल एक चीज मैं के साथ आया था:

my %hash = (key1=>"Something"); 
$hash{key2} = $hash{key1} . "Else"; 
+2

आप पहले दूसरे मूल्य को क्यों जोड़ नहीं सकते? चूंकि आप हैश बना रहे हैं, आप इसे जानते हैं। –

+0

आपके साथ आने के तरीके में क्या गलत है? :) –

उत्तर

11

मध्यवर्ती चर का उपयोग क्यों नहीं करें?

my $common_value = 'Something'; 
my %some_hash = (k1 => $common_value, k2 => $common_value.'Else'); 

अद्यतन

केम्प पूछा क्यों हम एक मध्यवर्ती चर की जरूरत है। मैं इस सवाल को दो तरीकों से समझ सकता हूं, मैं दोनों व्याख्याओं का उत्तर देने का प्रयास करूंगा।

  1. आप my %hash = (k1 => 'foo', k2 => $hash{k1}.'bar'); क्यों नहीं कर सकते?

    अभिव्यक्ति के दाईं ओर (rhs) का मूल्यांकन बाएं हाथ की ओर (एलएचएस) से पहले किया जाता है। इसलिए, जब k2 के लिए मान निर्धारित किया गया है, तो %hash पर कोई आकलन अभी तक नहीं हुआ है। वास्तव में, %hash अभी तक भी स्क्रैच पैड में नहीं बनाया गया है और दर्ज नहीं किया गया है। (%hash यहां एक व्याख्यात्मक चर है, इसलिए यह प्रतीक तालिका में नहीं जाएगा।)

  2. किसी अन्य विधि के बजाय एक चर का उपयोग क्यों करें?

    ठीक है, इस तरह के मूल्यों के साथ हैश शुरू करने के कई तरीके हैं। अगर मैं प्रारंभ करने के लिए संबंधित कुंजी की एक छोटी संख्या थी तो मैं एक मध्यवर्ती चर का उपयोग करूंगा।

    my $cv1 = sub_result() * 5; 
    my $cv2 = "Number: $cv1"; 
    
    my %h = (
        k1 => $cv1, 
        k2 => $cv2, 
        k3 => "Numero: $cv1", 
        k4 => "Big $cv2", 
        k5 => "Round $cv2", 
        k6 => "Whole $cv2", 
        k7 => "-$cv1", 
    ); 
    

    हालांकि, अगर मैं कई जटिल मूल्यों है कि कई अलग अलग चाबियाँ पर निर्भर बनाने के लिए किया था, मैं शायद एक डेटा संचालित दृष्टिकोण हैश प्रारंभ करने में उपयोग करेंगे। सटीक कार्यान्वयन विवरण मेरे पास नहीं है पर निर्भर करेगा, लेकिन यह कुछ इस तरह दिख सकता है:

    use Scalar::Util qw(reftype); 
    
    my @init = ( 
        [ key1 => $value     ], 
        [ key2 => \&make_a_value, 'key1' ], 
        [ key3 => \&another_way, 'key2' ], 
    ); 
    
    my %h; 
    for my $spec (@init) { 
        my $key = shift @$spec; 
        my $value = shift @$spec; 
        my @args = @$spec; 
    
        if(reftype $value eq reftype sub {}) { 
         $value = $value->(@h{ @args }); 
        } 
    
        $h{$key} = $value; 
    } 
    

    किसी भी मामले के लिए जहां यह सवाल arrises, के रूप में करने के लिए क्या तकनीक का उपयोग करने के विकल्प में बहुत सी जानकारियां हैं कि पर निर्भर करता है उस उदाहरण के लिए विशेष। इसलिए हमें सामान्य बयान देने की आवश्यकता के साथ छोड़ दिया गया है। इंटरमीडिएट वैरिएबल ओपी की समस्या से संपर्क करने का एक अच्छा तरीका है। चाहे उन्हें अपने विशेष मामले में इस्तेमाल किया जाना चाहिए, मैं नहीं कह सकता।

+0

एक मध्यवर्ती चर की आवश्यकता क्यों होगी? –

9

यह 2 कारणों के लिए नहीं किया जा सकता:

  1. समय पर्ल प्रक्रियाओं key2 => $hash{key1} में, यह अभी तक स्मृति आवंटित संबद्ध नहीं किए गए हैश नाम हैश के साथ कुंजी 1। दूसरे शब्दों में, $hash{key1}key2 => $hash{key1} के बाद तक स्मृति में सही जगह पर इंगित नहीं करता है।

  2. पिछला कारण अतिरिक्त समस्या राज्य नहीं था: यदि आप अभी तक बार जब आप पर कार्रवाई key2 => $hash{key1} (फिर से पार्स/मूल्यांकन के आदेश) द्वारा एक प्रतीक तालिका में %hash जगह नहीं किया, इसलिए संकलक barf होगा यदि आप use strict; जैसा कि आपको हमेशा करना चाहिए। यह पहले कथन में my %hash घोषित करने के साथ आसानी से ठीक हो सकता है, लेकिन # 1 नहीं है।

4

उस बिंदु पर जहां आप हैश को परिभाषित कर रहे हैं, $ हैश {key1} मौजूद नहीं है, इसलिए आप इसे एक कथन में नहीं कर सकते हैं। आप अपना स्वयं का समाधान कर सकते हैं और इसे परिभाषित करने के बाद कुंजी कुंजी 1 का उपयोग कर सकते हैं।

1

क्या

my %hash = (key1 => "Something", key2 => "Something" . "Else"); 

साथ गलत क्या है?

हां, मुझे पता है कि वे प्लेसहोल्डर्स हैं, लेकिन जब भी आप होश बनाते हैं तो आप उन्हें जानते हैं (या आप इसे बिल्कुल नहीं बनाएंगे), तो आप उन्हें एक साथ क्यों शामिल नहीं करते?

0

सबसे पहले, मैं इसे मध्यवर्ती मूल्य के साथ ही करूँगा। लेकिन, आपके पास दो अलग-अलग उन्नत विकल्प हैं। मेरा सुझाव है कि नहीं/या तो इनमें से/यदि आप पर्ल के लिए नए हैं - वास्तव में मैं नहीं बल्कि मध्यस्थ मूल्य समाधान सबसे अच्छा की तरह है, लेकिन पूर्णता के लिए:

  • आप Tie::Hash जो आपको एक बनाने की अनुमति देता का उपयोग कर सकते हैश सिंटैक्स और हैश स्टाइल डेरफ्रेंसिंग (->{key1}) के साथ सुलभ वस्तु, आप perldoc perltie के साथ इस विधि पर अधिक जानकारी प्राप्त कर सकते हैं, और Tie::Hash के लिए ऊपर दिए गए मैन पेज;
  • आप हैश का उपयोग करने के विचार को छोड़ सकते हैं; और, किसी ऑब्जेक्ट का उपयोग करें, या यहां तक ​​कि Moose जो आपको ऑब्जेक्ट को हैश से प्रारंभ करने की अनुमति देगा, वही मान साझा करेगा। मुझे ऐसा करने में वास्तविक दुनिया के उदाहरण में ज्यादा उद्देश्य नहीं दिख रहा है।

यहां एक मूस उदाहरण है।

package Class; 
use Moose; 
has [qw/key1 key2/] => (isa => 'Str', is => 'rw', init_arg => 'key1'); 

my $o = Class->new({ key1 => 'foobar' }); 
print $o->key1, $o->key2; 
0

आप काफी नजदीकी प्राप्त कर सकते हैं, लेकिन मुझे यकीन है कि यह नवीनता के अलावा अन्य महत्व है नहीं कर रहा हूँ:

$_->{key2} = $_->{key1} . "Else" for my $hash = { key1 => "Something" }; 
0

तो मध्यवर्ती चर बनाने के बाहर% हैश के, डाल तो का उपयोग कर बंद है एक do block इसे और अधिक सौंदर्य की दृष्टि से मनभावन कर सकते हैं:

my %hash = (
    do { 
     my $s = 'Something'; 
     (key1 => $s, key2 => $s . 'Else'); 
    }, 
); 

/I3az/

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