2010-07-30 12 views
6
में शैली गुजर

मैं लोगों को पर्ल में नामित पैरामीटर प्रदान करने के लिए दो शैलियों का उपयोग कर देखें:पैरामीटर पर्ल

use strict; 
use warnings; 
use Data::Dumper; 

sub foo { 
    print Dumper @_; 
} 

sub bar { 
    print Dumper @_; 
} 

foo(A => 'a', B => 'b'); 
bar({ A => 'a', B => 'b' }); 

foo() बजाय शैली बार() शैली का प्रयोग करने में क्या लाभ हैं?

उत्तर

9

दूसरी विधि हैश के संदर्भ को पास करती है, जबकि पहले सिर्फ एक सूची पास करती है।

यहां दो पहलू हैं: सिद्धांत रूप में, प्रदर्शन के संदर्भ में हैश का संदर्भ बेहतर हो सकता है, हालांकि लघु तर्क सूचियों के लिए यह नगण्य है। foo(a => 1, b => 2) जैसे साधारण कॉल के लिए कोई प्रदर्शन अंतर नहीं है, क्योंकि @_ वास्तव में मूल मानों के लिए उपनाम है।

लेकिन अगर कॉलर के पास पहले से हैश में मान हैं, तो पहली शैली में हैश से सूची में रूपांतरण की आवश्यकता होती है, और उसके बाद फिर से हैश, जो धीमा हो सकता है।

दूसरा पहलू सवाल है जो हैश में रूपांतरण के लिए ज़िम्मेदार है। पहली शैली इसे फ़ंक्शन कहलाती है, और यदि यह my %args = @_ करता है, तो यह तर्कसंगत चेतावनियां उत्पन्न करेगा यदि तर्क सूची भी लंबाई की नहीं है।

यही कारण है कि मैं दूसरी शैली को थोड़ा पसंद करता हूं (या मैं पर्ल 6 का उपयोग करता हूं, जो नामित तर्कों का समर्थन करता है)।

+1

+1। –

+1

ये "प्रदर्शन पहलू" अनावश्यक सूक्ष्म अनुकूलन हैं जो कोई व्यावहारिक लाभ नहीं देते हैं। एक हैश को आसानी से एक सूची के रूप में उपयोग किया जा सकता है: 'foo (% हैश) 'या हैशफ:' foo (% {$ हैशफ})'। Foo शैली के साथ चिपके हुए उपयोगकर्ता को अधिक शक्ति छोड़ देता है। – jmz

+0

दरअसल, मेरा स्वयं का बेंचमार्किंग दिखाया गया है (कई प्रतिष्ठानों पर) कि संदर्भों की तुलना में सूचियों को पार करना तेज़ है - हालांकि यह * वापसी * ​​संदर्भों के लिए तेज़ी से दिखाई देता है। – Axeman

5

सबसे पहले, दो तरीकों में से एक स्पष्टीकरण:

sub foo { 
    # Transform the array to a hash 
    my %args = @_; 

    foreach my $key (keys %args) { 
     print "$key => $args{$key}\n"; 
    } 
} 

# Pass an array of values 
foo(A=>'a', B=>'b'); 

इस पहले मामले में सभी आप कर रहे हैं एक सरणी से गुजर रहा है। इस संदर्भ में => हैश कुंजी/मान सूचक नहीं है जिसे आप सोच सकते हैं। इस संदर्भ में यह सिर्फ "वसा कॉमा" है।

sub bar { 
    my ($hash_ref) = @_; 
    foreach my $key (keys %$hash_ref) { 
     print "$key => $hash_ref->{$key}\n"; 
    } 
} 

# pass a ref to an anonymous hash 
bar({ A=>'a', B=>'b' }); 

इस दूसरे मामले में आप एक गुमनाम हैश बनाने और कार्य करने के लिए तर्क के रूप में है कि हैश के लिए एक संदर्भ गुजर रहे हैं।

दूसरे पर एक क्यों चुनें? पुस्तक में, पर्ल बेस्ट प्रैक्टिसिस, शीर्षक "नामांकित तर्क" शीर्षक के तहत अध्याय 9 लेखक इस समारोह में तीन से अधिक तर्क होने पर दूसरी शैली का उपयोग करने की सिफारिश करता है। वह इसे भी पसंद करता है क्योंकि यह रन टाइम के बजाए संकलन समय पर विवादित संख्याओं के तर्कों को पकड़ता है।

+3

यह थोड़ी देर के बाद से मैंने इसे पढ़ा है, लेकिन मैंने सोचा कि 3+ तर्कों के साथ हैशफ का उपयोग करने की सिफारिश मानक नामांकित तर्क सूची के बजाय थी, यानी 'foo (' a ',' b ')' को कॉल करने के बजाय हैश पर हैशफ्स की सिफारिश – plusplus

+3

@ प्लसप्लस: सेक्शन का शीर्षक है: "किसी भी सबराउटिन के लिए नामांकित बहस के हैश का उपयोग करें जिसमें तीन से अधिक बहस हैं।" टुकड़े के शरीर में वह विशेष रूप से एक हैश में परिवर्तित कच्चे नाम/मूल्य जोड़े पर हैश रेफ का उपयोग करने के लिए कहता है। आपके संदर्भ को निर्दिष्ट करने के लिए –

+0

+1। प्रदर्शन पहलुओं को इंगित करने के लिए –

6

foo(a => 1, b => 2) शैली नामित तर्कों को अनुकरण करने का सामान्य तरीका है। bar({a => 1, b => 2}) आमतौर पर केवल पूरक (और संभवतः वैकल्पिक) तर्कों के लिए उपयोग किया जाता है।

सामान्य उपयोग के लिए, मैं पहला फॉर्म पसंद करता हूं। {} अतिरिक्त टाइपिंग, पढ़ने के लिए अतिरिक्त शोर, और यदि आप या तो दोनों ब्रेसिज़ छोड़ते हैं तो एक संभावित त्रुटि बनाते हैं। कोई प्रदर्शन अंतर नगण्य है। (यदि ऐसा नहीं है, तो आपको बड़ी समस्याएं हैं।) दूसरी तरफ, अज्ञात हैश कन्स्ट्रक्टर में तर्कों को लपेटने से रनटाइम की बजाय संकलन-समय पर त्रुटियों को ढूंढने में आपकी सहायता मिल सकती है।

दूसरा रूप आमतौर पर स्थितित्मक तर्कों के साथ मिश्रित देखा जाता है। जैसेबेंचमार्क से करता है:

cmpthese(10000, { 
    foo => \&foo, 
    bar => \&bar, 
}); 

टी {} बाहर छोड़ देता है जबकि:

my $text = $w->Scrolled('Text', -width => 80, -height => 50); 

यह आमतौर पर एक शैलीगत विकल्प है।