2010-09-03 6 views
10

पर्ल 5.10 ने given/when के साथ एक उचित स्विच निर्माण शुरू किया और यह एक शक्तिशाली उपकरण की तरह लगता है।दिए गए/कब के लिए किस प्रकार के स्वच्छ उपयोग के मामले मौजूद हैं?

वर्तमान में, perldoc perlsyn में कुछ अच्छे उदाहरणों की कमी है।

given (-d "foo/bar/") { 
    when (1) { ... } # defined is wrong as -d returns '' on a file. 
    default { ... } 
} 

या वैकल्पिक रूप से:

एक मामले में जहां मैं इसे आसान पाया हाल ही में फ़ाइल परीक्षण ऑपरेटरों के साथ यह प्रयोग करने के लिए था

given ("foo/bar/") { 
    when (-d) { ... } 
    default { ... } 
} 

मेरे लिए, विशेष रूप से पहला संस्करण एक की तुलना में बेहतर है, तो लग रहा है टेस्टरी ऑपरेटर का निर्माण या उपयोग करते समय, परीक्षण के नतीजे के आधार पर मुझे दोनों मामलों में कार्रवाई करने की आवश्यकता होती है।

यह मुझे आश्चर्यचकित कर देता है, हालांकि स्मार्ट मिलान से वापस आने के सामान्य मामले से परे और साफ-सुथरा दिखता है और अगर-एलीफ-एल्सिफ़ -..-अन्य संरचनाओं से परहेज करते हैं?

मेरे पास एक झुकाव है जो स्पष्टता खोने के बिना चालाक होने के लिए दिया जाता है/लेकिन मेरे पास कोई अच्छा उदाहरण नहीं है।

given ($filename) { 
     when (-e) { 
       when (-f) { 
         when (-z) { say "Empty file" } 
         default { say "Nonempty file" } 
       } 
       when (-d) { 
         when (-o) { say "Directory owned by me"} 
         default { say "Directory owned by someone else" } 
       } 
       default { say "Special" } 
     } 
     default { say "No such file or directory" } } 
+1

आप 'stat' कॉल करने से बचने के लिए '-f _',' -z _', '-d _', और' -o _' का उपयोग करना चाह सकते हैं एक ही फाइल '-e' इसे बुलाया। अधिक जानकारी के लिए ['perldoc -f -X'] (http://perldoc.perl.org/functions/-X.html) देखें। –

+0

दरअसल, आमतौर पर कैश किए गए फॉर्म का उपयोग करना एक अच्छा विचार है। मैं हालांकि असंबंधित चीजों के साथ उदाहरण को खत्म नहीं करना चाहता था। यह शायद ही कभी प्रदर्शन के लिए महत्वपूर्ण है ... – szbalint

+0

'-d' encompasses '-e' और' -f' encompasses'-e', '-e' का परीक्षण करने का कोई कारण नहीं है जब तक'! -f &&! -d' , यह मानने के लिए कुछ भी नहीं बदलेगा कि उस मामले में, यदि '-e', तो यह विशेष है। – Axeman

उत्तर

3

एक recent answer ज़ैद के सवाल Strategies to handle a file with multiple fixed formats लिए, मैं एक गरीब आदमी का याक जिसका मुख्य पाश की एक सरणी की खोज के साथ समाप्त हो गया में:

एक बात है कि मुझे हालांकि हैरान कर दिया, आप घोंसला निर्माण में अच्छी तरह से कर सकते हैं वह यह है कि पहले मैच के लिए नियमित अभिव्यक्ति:

while (<>) { 
    given($_) { 
    when (@{[ map $pattern{$_}, @expect ]}) {} 
    default { 
     die "$0: line $.: expected " . join("|" => @expect) . "; got\n$_"; 
    } 
    } 
} 

एक और सवाल में, David B wanted to match against multiple regexes, और my answer uses smart matching को परोक्ष regexes से अधिक पाश:

#! /usr/bin/perl 

use warnings; 
use strict; 

use feature 'switch'; 

my @patterns = (
    qr/foo/, 
    qr/bar/, 
    qr/baz/, 
); 

for (qw/ blurfl bar quux foo baz /) { 
    print "$_: "; 
    given ($_) { 
    when (@patterns) { 
     print "hit!\n"; 
    } 
    default { 
     print "miss.\n"; 
    } 
    } 
} 
+2

'दिया गया कथन थोड़ा कष्टप्रद है। क्या कोई कारण है कि 'while' को topicalizer के रूप में उपयोग नहीं किया जा सकता है? –

2
नीचे अगर एक साफ उपयोग के मामले या सिर्फ टोपी के एक टिप पर्ल की भाषाई वंश :)

# things todo (or should have done!) at this time of the day: 

given (TheTime->of_day) { 

    when ('morning') { 
     breakfast(); 
     make_packed_lunch() if $_->is_work_day; 
    } 

    lunch() when 'afternoon'; 

    when ('evening') { 
     goto_pub() if $_->is_friday; 
     dinner(); 
    } 

    default { say "Should be sleeping if its " . $_->{dt}->ymd } 
} 

है

पता नहीं है और अगर आप देखने $_ है "यह" तो यह विशेष रूप से अच्छी तरह से काम करता है (आईएमएचओ)।

उपर्युक्त काम overloading स्मार्ट मैच ऑपरेटर जो given/when पर भरोसा करता है। यहाँ कैसे TheTime वर्ग मेरी उदाहरण काम करने के लिए लिखा जा सकता है:

{ 
    package TheTime; 
    use DateTime; 
    use overload '~~' => '_check_hour', fallback => 1; 

    our %day_time = (
     morning => [0..11], 
     afternoon => [12..17], 
     evening => [18..23], 
    ); 

    sub of_day { 
     my $class = shift; 
     bless { 
      dt => DateTime->now, 
     }, $class; 
    } 

    sub is_work_day { shift->{dt}->day_of_week ~~ [1..5] } 
    sub is_friday { shift->{dt}->day_of_week == 5  } 

    sub _check_hour { 
     my ($self, $greeting) = @_; 
     $self->{dt}->hour ~~ $day_time{$greeting}; 
    } 
} 

/I3az/

पी एस। यह ब्लॉग पोस्ट मैंने हाल ही में किया है: given/when – the Perl switch statement

+1

+1: 'अधिभार' का अच्छा उपयोग – dawg

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