क्या आप पर्ल में एक सरणी होने के लिए या तो स्केलर या सरणी को रेफरी कर सकते हैं?

मेरे पास एक perl चर $ परिणाम है जो किसी सेवा से वापस आ जाता है। मान को सरणी माना जाता है, और $ परिणाम एक सरणी संदर्भ होना चाहिए। हालांकि, जब सरणी में केवल एक आइटम होता है, तो $ results उस मान पर सेट किया जाएगा, और एक संदर्भित सरणी नहीं जिसमें उस आइटम को शामिल किया गया हो।

मैं अपेक्षित सरणी पर foreach लूप करना चाहता हूं। ref ($ results) eq 'ARRAY' की जांच किए बिना, क्या निम्न के बराबर कुछ करने का कोई तरीका है:

foreach my $result (@$results) {
    # Process $result
}

वह विशेष कोड नमूना संदर्भ के लिए काम करेगा, लेकिन सरल स्केलर के लिए शिकायत करेगा।

संपादित करें: मुझे यह स्पष्ट करना चाहिए कि सेवा से लौटाए जाने के लिए मेरे पास कोई रास्ता नहीं है। समस्या यह है कि मूल्य एक स्केलर होगा जब केवल एक मान होगा और एक से अधिक मान होने पर यह एक सरणी संदर्भ होगा।

0
जोड़ा संपादित
विचारों: 2
यह व्यवहार मुझे चिल्लाना और पसंद करना चाहता है, "स्थिर PERL!" लेकिन फिर मुझे एहसास हुआ कि जिन भाषाओं को इस बकवास की आवश्यकता नहीं है, वे अभी भी हुड के नीचे कर रहे हैं, जिससे यह मुझे थोड़ा कम परेशान करता है ....
जोड़ा लेखक Rooster, स्रोत

5 उत्तर

मैंने अभी इसका परीक्षण किया है:

  #! / usr / bin / perl -w
सख्त उपयोग करें;

सब टेस्टिट {

 मेरा @ret = ();
 अगर (शिफ्ट) {
   पुश @ रेट, 1;
   पुश @ रेट, 2;
   पुश @ रेट, 3;
}अन्य{
  पुश @ret, "अकेला";
}

वापसी \ @ret;
}

मेरे $ आर (@ {testit (1)} foreach() {
  प्रिंट $ आर। "test1 \ n";
}
मेरा $ आर (@ {testit ()} foreach ({
   प्रिंट $ आर। "test2 \ n";
}
 

और ऐसा लगता है कि यह ठीक काम करता है, इसलिए मुझे लगता है कि सेवा से लौटने के परिणाम के साथ इसका कुछ संबंध है? यदि आपके पास लौटने वाली सेवा पर कोई नियंत्रण नहीं है तो यह क्रैक करने के लिए कठिन हो सकता है

0
जोड़ा

मुझे यकीन नहीं है कि इससे कोई अन्य तरीका है:

  $ result = [$ परिणाम] अगर रेफरी ($ परिणाम) ne 'ARRAY';
प्रत्येक के लिए .....
 
0
जोड़ा

ठीक है अगर आप नहीं कर सकते ...

for my $result ( ref $results eq 'ARRAY' ? @$results : $results ) {
    # Process result
}

या यह...

for my $result ( ! ref $results ? $results : @$results ) {
    # Process result
}

तो आपको इस तरह कुछ बालों वाली डरावनी कोशिश करनी पड़ सकती है!

for my $result ( eval { @$results }, eval $results ) {
    # Process result
}

और उस खतरनाक स्ट्रिंग से बचने के लिए यह वास्तव में बदसूरत हो जाता है !!

for my $result ( eval { $results->[0] } || $results, eval { @$results[1 .. $#{ $results }] } ) {
    # Process result
}

पुनश्च। मेरी प्राथमिकता इसे उप-कॉल कॉल_to_service() उदाहरण में रीटमन द्वारा दिया गया है।

0
जोड़ा
यह एक स्ट्रिंग eval नहीं है। और लूपिंग (कुछ अभिव्यक्तियां @ $ परिणाम शामिल हैं) लूपिंग (@ $ परिणाम) से बहुत अलग है। पूर्व सरणी (उपभोग करने वाली स्मृति) की प्रतिलिपि बनायेगा; उत्तरार्द्ध इसके लिए उपनाम करेगा (और लूप चर के माध्यम से तत्वों को संशोधित करने की अनुमति देगा)।
जोड़ा लेखक ysth, स्रोत
@ysth - वहाँ है ... देखें "eval $ परिणाम"। मेरा सुझाव पहले दिया गया call_to_service() उदाहरण का उपयोग करना था। मेरा जवाब पोस्टर द्वारा लगाए गए प्रतिबंध के लिए "गाल समाधान में जीभ" का थोड़ा सा था, इसलिए हां इसकी त्रुटियों को इंगित करने के लिए अच्छा है।
जोड़ा लेखक draegtun, स्रोत

मैं लूप के अंदर कोड फिर से कारक करूँगा और फिर करता हूं

if( ref $results eq 'ARRAY' ){
    my_sub($result) for my $result (@$results);
}else{
    my_sub($results);
}

बेशक मैं केवल तभी ऐसा करूंगा यदि लूप में कोड गैर-तुच्छ था।

0
जोड़ा

एक और समाधान कॉल को सर्वर पर लपेटना होगा और अपने जीवन के बाकी हिस्सों को सरल बनाने के लिए हमेशा एक सरणी वापस कर देना होगा:

sub call_to_service
{
    my $returnValue = service::call();

    if (ref($returnValue) eq "ARRAY")
    {
        return($returnValue);
    }
    else
    {
       return( [$returnValue] );
    }
}

फिर आप हमेशा यह जान सकते हैं कि आप एक सरणी का संदर्भ वापस ले लेंगे, भले ही यह केवल एक आइटम था।

foreach my $item (@{call_to_service()})
{
  ...
}
0
जोड़ा