2015-08-10 18 views
6

जब निम्न कोड के दुष्प्रभाव हो सकते हैं?

@some = map { s/xxx/y/; $_ } @some; 

perlcritic, यह के रूप में खतरनाक बताते हैं क्योंकि उदाहरण के लिए:

@other = map { s/xxx/y/; $_ } @some; 

और @some के सदस्यों भी संशोधित मिला है। समझना। मैं BPB किताब है, और यह उदाहरण

@pm_files_without_pl_files 
     = grep { s/.pm\z/.pl/xms && !-e } @pm_files; 

और यह भी मैं अध्याय "सूची प्रसंस्करण साइड इफेक्ट्स" पढ़ा/के साथ ऊपर से पता चलता "कभी एक सूची समारोह में $ _ संशोधित करते हैं।" और उसके अनुयायियों। इसके अलावा मुझे /r पता है।

स्पष्ट है (के रूप में ज्यादा मेरी भयानक अंग्रेजी के साथ संभव है):

1 उदाहरण में मुख्य बिंदु मूल @some को संशोधित किया गया है।

  • सकता है 1 उदाहरण@some = map { s/xxx/y/; $_ } @some;कुछ अवांछित दुष्प्रभाव के कारण:

    प्रश्न के बारे में है? यदि हां, तो कब?

  • या यह सिर्फ "अनुमोदित नहीं" तरीका है (लेकिन हानिरहित अन्यथा)?

कुछ "perl beginner की पुस्तक" के रूप में थोड़ा गहराई से उत्तर देने के लिए एक उत्तर खोज रहे हैं - इसलिए अभी भी कोई भी वर्तमान उत्तर स्वीकार नहीं किया गया है। ;)

+2

गैर विनाशकारी 'r' संशोधक जोड़ने का प्रयास करें:' मानचित्र {s/xxx/y/आर} 'पर्ल 5.13.2 से उपलब्ध है, देखें http://www.effectiveperlprogramming.com/2010/12/perl-5-14-adds-non-destructive-transliteration/ –

+0

आलोचक के लिए पृष्ठभूमि अध्याय 5 में वर्णित है [पुस्तक] (http://shop.oreilly.com/product/9780596001735.do) –

+0

@ हाकॉनहेग्लैंड - मेरे पास किताब है, और इसे भी पढ़ा गया है ... प्रश्न को संपादित करने के लिए (मुझे उम्मीद है) और अधिक स्पष्ट। – cajwine

उत्तर

11

पेर्ल के मोटो में से एक हमेशा टिमटोटीआई रहा है: ऐसा करने के एक से अधिक तरीके हैं। यदि दो तरीकों का एक ही अंतिम परिणाम होता है, तो वे समान रूप से सही होते हैं। इसका मतलब यह नहीं है कि दूसरे पर एक तरह से पसंद करने के कारण नहीं हैं।

पहले मामले में, यह (मेरे लिए, YMMV) की तरह

s/xxx/y/ for @some; 

यह मुख्य रूप से है क्योंकि यह इरादा संवाद स्थापित कर रहा है बेहतर है कुछ करने के लिए और अधिक स्पष्ट हो जाएगा। for सुझाव देता है कि यह सब दुष्प्रभाव के बारे में है, जबकि map सुझाव देता है कि यह वापसी मूल्य के बारे में है। कार्यात्मक रूप से समान होने पर, यह आपके साथी प्रोग्रामर (और संभवतः अब से 6 महीने में अपने लिए) के लिए समझना बहुत आसान होना चाहिए।

एक से अधिक तरीके हैं, लेकिन कुछ दूसरों की तुलना में बेहतर हैं।

+0

प्रश्न संपादित किया (मुझे आशा है) यह अब और स्पष्ट है। – cajwine

+0

@cajwine: बेहतर? –

7

कोड अपने उदाहरण की तरह:

@some = map { s/xxx/y/; $_ } @some; 

क्योंकि यह निरर्थक और भ्रामक है बचा जाना चाहिए। यह जैसा दिखता है बाईं ओर असाइनमेंट कुछ करना चाहिए, भले ही यह वास्तव में नो-ऑप हो।दरअसल, सिर्फ लेखन:

map { s/xxx/y/; $_ } @some; 

ठीक उसी असर पड़ेगा, के रूप में होगा:

map { s/xxx/y/ } @some; 

इस संस्करण में कम से कम इसे बनाने के आधार पर किया गया है (यथोचित) स्पष्ट है कि map की वापसी मान है अनदेखा किया जा रहा है, और बयान का वास्तविक उद्देश्य @some को जगह में संशोधित करना है।

लेकिन ज़ाहिर है, के रूप में लियोन पहले ही बताया गया है, अब तक इस लेखन का सबसे स्पष्ट मुहावरेदार तरीका होगा:

s/xxx/y/ for @some; 
+0

प्रश्न संपादित (मुझे आशा है) यह अब और स्पष्ट है। – cajwine

3
@some = map { s/xxx/y/; $_ } @some; 

अच्छा काम होगा, लेकिन यह बहुत ही गरीब कोड है क्योंकि यह नहीं स्पष्ट है कि आप प्रभावी रूप से

map { s/xxx/y/ } @some; @some = @some; 

कर रहे हैं यह पहले से ही पता चलता है तो आप बस कर सकते थे

map { s/xxx/y/ } @some; 

लेकिन उस

s/xxx/y/ for @some; 

की एक भ्रामक और अक्षम संस्करण है यह सब पठनीयता और रख-रखाव के बारे में है।


ध्यान दें कि आप

use List::MoreUtils qw(apply); 

@some = apply { s/xxx/y/ } @some; 

और पर्ल 5.14+ में कर सकते हैं,

@some = map { s/xxx/y/r } @some; 
संबंधित मुद्दे