2012-01-16 6 views
8

(बहुत सराहना) perlmonks साइट पर, मैं एक स्ट्रिंग के दोनों ओर से following snippet that trims स्थान नहीं मिले:पर्ल में, क्या फ़ंक्शन वांछरे नृत्य करना चाहिए, या क्या हम कॉलर को मानचित्र का उपयोग करने की उम्मीद कर सकते हैं?

sub trim { 
    @_ = $_ if not @_ and defined wantarray; 
    @_ = @_ if defined wantarray; 
    for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// } 
    return wantarray ? @_ : $_[0] if defined wantarray; 
} 

मुझे समझ नहीं आता क्यों लेखक wantarray लगभग हर लाइन की जाँच के सभी परेशान करने के लिए चला जाता है । क्यों न केवल स्ट्रिंग को ट्रिम करें, और प्रोग्रामर map का उपयोग करें जब वह सरणी पास कर रहा हो?

क्या कि ट्रिम के बीच का अंतर, इस तरह कहा जाता है:

my @test_array = ('string1', ' string2', 'string3 ', ' string4 '); 
my @result = map { trim($_) } @test_array; 
+0

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

+1

संबंधित: [पर्ल में ट्रिम] (https://plus.google.com/105725977711317285348/posts/ienzxqHJmRe) – daxim

+0

वांछे और इसी तरह के जादू की छल एक उग्र हैं। जब तक आपको करना नहीं है तब तक चालाक प्रोग्रामिंग न करें। एपीआई चालाक कभी नहीं। – tsee

उत्तर

11

सबसे पहले यह बेहतर है अगर तुम सार यह है कि दूर नक्शा:

#e.1. 
sub trim 
{ 
    my @ar = @_; 
    for (@ar) { s/^\s+//, s/\s+$// }; 
    return wantarray ? @ar : $ar[0]; 
} 

दूसरा, ऊपर के उदाहरण पर विचार करें और से इसकी तुलना:

#e.2. 
sub trim 
{ 
    for (@_) { s/^\s+//, s/\s+$// }; 
} 

क्या अंतर?

ई .1। ई 2 के दौरान एक नई छंटनी सरणी देता है। मूल सरणी को संशोधित करता है।

ठीक है, मूल क्रिप्टिक सबराउटिन क्या करता है?

यह ऑटो जादुई (yeaah, यह पर्ल है) मूल सरणी को संशोधित करता है अगर आप कुछ भी करने के लिए वापसी मान निर्दिष्ट नहीं कर रहे हैं या अछूता मूल सरणी छोड़ देता है और एक नया छंटनी की सरणी रिटर्न अगर आप वापसी मान निर्दिष्ट कर रहे हैं एक और चर पर।

कैसे?

यह देखने के लिए कि क्या वांछरे को परिभाषित किया गया है या नहीं। जब तक कार्य दाएं हाथ पर होता है और वापसी मान एक परिवर्तनीय "परिभाषित वांछित" को असाइन किया जाता है (स्केलर/सरणी संदर्भ के बावजूद)।

+2

लेखक यह भी चाहता है कि फ़ंक्शन में कोई तर्क पारित न होने पर फ़ंक्शन को '_ _' पर काम करना पड़े। – mob

+0

तो, आप प्रत्येक समारोह को LIST और SCALAR दोनों को स्वीकार करने की पेशकश करेंगे, इसलिए कॉलर को मानचित्र को स्वयं लिखना नहीं है? मुझे विचार पसंद है, लेकिन दो चीजें मुझे दूर रखती हैं: 1. ओवरहेड जब जरूरत नहीं है; 2. शून्य/स्केलर/सूची संदर्भ को संभालने के लिए कोड की कॉपी-पेस्टिंग (1 की बजाय 4 लाइनें)। – Konerak

+0

स्वीकार नहीं करना है (वैसे भी आपके पैरामीटर subroutine में @_ पर जाएंगे) लेकिन वापस लौटने के लिए। और यह वापसी वांछित के साथ हासिल किया जा सकता है? @ar: $ ar [0]; बयान। मूल 4-लाइनर बहुत कुछ कर रहा है जो स्केलर/सूची का ख्याल रखता है जैसा कि मैंने ऊपर वर्णित करने की कोशिश की थी। –

5

शायद लेखक चाहता था: जब एक एक सरणी ट्रिम करने के लिए की जरूरत है

my @test_array = ('string1', ' string2', 'string3 ', ' string4 '); 
my @result = trim(@test_array); 

या एक सरल ट्रिम, इस तरह कहा जाता है मानक chomp फ़ंक्शन के व्यवहार की नकल करने के लिए। अपने काम में ऐसा करने की कोई ज़रूरत नहीं है।

man perlfunc 
chomp VARIABLE 
chomp(LIST) 
chomp 

[...] आप एक सूची chomp हैं, तो प्रत्येक तत्व chomped है। [...]

+0

मुझे लगता है कि चोंप –

+0

में इस तरह के व्यवहार से वांछित करने के लिए कुछ भी नहीं है, चॉम्प मूल सरणी को संशोधित कर रहा है, इसलिए यह उतना आसान हो सकता है: sub chomp {for (@_) s/blah/blah /} –

+0

युप, आप हैं सही। वास्तव में 'वांछरे' परिभाषित हो जाता है जब कॉलर स्केलर की अपेक्षा करता है। – kubanczyk

1

ध्यान दें कि यह वास्तव में Text::Trim लागू किया गया है। विभिन्न उपयोग-मामलों पर इसका विवरण देखें। wantarray के साथ नाटकों विभिन्न संदर्भों को अलग करने और प्रत्येक के लिए विभिन्न अर्थशास्त्र लागू करने की अनुमति देता है।

व्यक्तिगत रूप से मैं केवल एकल अर्थशास्त्र पसंद करता हूं क्योंकि इसे समझना और उपयोग करना आसान है। मैं नायलॉन स्माइल के उदाहरण 1 के साथ, $_ डिफ़ॉल्ट परिवर्तनीय या स्थान पर संशोधन का उपयोग करने से बचूंगा।

7

लाइन द्वारा इस रेखा के नीचे तोड़कर के बाद से यह नहीं किया गया है:

sub trim { 
    @_ = $_ if not @_ and defined wantarray; 
    # if there are no arguments, but a return value is requested 
    # then place a copy of $_ into @_ to work on 

    @_ = @_ if defined wantarray; 
    # if the caller expects a return value, copy the values in @_ into itself 
    # (this breaks the aliasing to the caller's variables) 

    for (@_ ? @_ : $_) { s/^\s+//, s/\s+$// } 
    # perform the substitution, in place, on either @_ or $_ depending on 
    # if arguments were passed to the function 

    return wantarray ? @_ : $_[0] if defined wantarray; 
    # if called in list context, return @_, otherwise $_[0] 
} 

मुझे लगता है कि कोड wantarray चेकों के सभी के साथ एक सा कठिन हो जाता है इस बात से सहमत है, लेकिन परिणाम एक समारोह है कि एक स्तर के शेयरों है पर्ल के बिल्टिन कार्यों के साथ लचीलापन का। फ़ंक्शन "स्मार्ट" बनाने का शुद्ध परिणाम कॉल साइट को साफ करना है (लूपिंग संरचनाओं, अस्थायी चर, पुनरावृत्ति, ... से बचने के लिए) जो आवृत्ति के आधार पर फ़ंक्शन का उपयोग किया जाता है, अर्थात् कोड पठनीयता में सुधार कर सकता है।

sub trim { 
    @_ = @_ ? @_ : $_ if defined wantarray; 

    s/^\s+//, s/\s+$// for @_ ? @_ : $_; 

    wantarray ? @_ : shift 
} 

पहले दो लाइनों, एक में लुढ़काया जा सकता है, क्योंकि वे एक ही बात (@_ को बताए) बस विभिन्न स्रोत मूल्यों के साथ कर रहे हैं:

समारोह एक छोटा सा सरल किया जा सकता है। और बाहरी return ... if defined wantarray अंत में जांच करने की कोई आवश्यकता नहीं है, क्योंकि शून्य संदर्भ में मूल्य लौटने से वैसे भी कुछ भी नहीं होता है।

लेकिन शायद मैं अंतिम पंक्ति को wantarray ? @_ : pop पर बदल दूंगा क्योंकि इससे यह एक सूची (स्केलर संदर्भ में अंतिम तत्व) जैसा व्यवहार करता है।

सब एक बार कहा और किया जाता है, यह अनुमति देता है निम्नलिखित बुला शैलियों में इस्तेमाल किया जा करने के लिए:

my @test_array = ('string1', ' string2', 'string3 ', ' string4 '); 

my @result = trim @test_array; 
my $result = trim $test_array[0]; 
trim @test_array; # in place trim 

और यहां तक ​​कि अभी भी कॉल साइट पाश का समर्थन करता है:

my @result = map trim, @test_array; 

या वरबोस रूप में दर्शा रूप में:

my @result = map trim($_), @test_array; 

और इसका उपयोग थोड़ी देर के अंदरके समान किया जा सकता है

while (<$file_handle>) { 
    trim; 
    # do something 
} 

पर्ल में dwimmery के बारे में राय मिश्रित हैं। मुझे व्यक्तिगत रूप से यह पसंद है जब फ़ंक्शंस मुझे कॉलर को कोड करने के लिए लचीलापन देता है जो किसी फ़ंक्शन के कठोर इंटरफ़ेस के आसपास काम करने के बजाय समझ में आता है।

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