वन-लाइनर्स बनाम पठनीयता: कोड को कम करना कब बंद करें? [बन्द है]


14

प्रसंग

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

इन दिनों, मैं ज्यादातर रूबी में कोड करता हूं, इसलिए मैंने अपने कोड की "गुणवत्ता" (समुदाय संचालित परियोजना रूबी-शैली-गाइड द्वारा परिभाषित की जा रही "गुणवत्ता" पर मुझे कुछ जानकारी प्रदान करने के लिए एक लिंटर (रूबोकॉप) का उपयोग करना शुरू कर दिया ।

ध्यान दें कि मैं "गुणवत्ता" का उपयोग "फ़ॉर्मेटिंग की गुणवत्ता" के रूप में करूंगा, कोड की दक्षता के बारे में इतना नहीं, भले ही कुछ मामलों में, कोड दक्षता वास्तव में प्रभावित होती है कि कोड कैसे लिखा जाता है।

वैसे भी, सब कुछ करते हुए, मुझे एहसास हुआ (या कम से कम, याद है) कुछ बातें:

  • कुछ भाषाएं (विशेष रूप से पायथन, रूबी और ऐसी) कोड के महान वन-लाइनर्स बनाने की अनुमति देती हैं
  • आपके कोड के लिए कुछ दिशानिर्देशों का पालन करने से यह काफी कम हो सकता है और फिर भी बहुत स्पष्ट हो सकता है
  • फिर भी, इन दिशानिर्देशों का सख्ती से पालन करने से कोड कम स्पष्ट / पढ़ने में आसान हो सकता है
  • कोड लगभग पूरी तरह से और अभी भी खराब गुणवत्ता के कुछ दिशानिर्देशों का सम्मान कर सकता है
  • कोड पठनीयता ज्यादातर व्यक्तिपरक है (जैसा कि "मुझे जो स्पष्ट है वह एक साथी डेवलपर के लिए पूरी तरह से अस्पष्ट हो सकता है")

वे केवल अवलोकन हैं, निश्चित रूप से पूर्ण नियम नहीं हैं। आप यह भी नोट करेंगे कि कोड पठनीयता और निम्नलिखित दिशानिर्देश इस बिंदु पर असंबंधित लग सकते हैं, लेकिन यहां दिशानिर्देश एक तरह से कोड की एक संख्या को फिर से लिखने के लिए संकीर्ण हैं।

अब, कुछ उदाहरण, उन सभी को और अधिक स्पष्ट करने के लिए।

उदाहरण

चलो एक सरल उपयोग मामला लेते हैं: हमारे पास एक " User" मॉडल के साथ एक आवेदन है । एक उपयोगकर्ता वैकल्पिक है firstnameऔर surnameऔर एक अनिवार्य emailपता।

मैं एक विधि लिखना चाहता हूं " name" जो firstname + surnameउपयोगकर्ता के नाम ( ) में वापस आ जाएगी यदि कम से कम उसका firstnameया surnameमौजूद है, या emailयदि नहीं तो एक कमबैक मान के रूप में।

मैं यह विधि भी चाहता हूं use_emailकि पैरामीटर (बूलियन) के रूप में एक " " लेने के लिए, उपयोगकर्ता ईमेल को फॉलबैक मूल्य के रूप में उपयोग करने की अनुमति देता है। यह " use_email" पैरामीटर डिफ़ॉल्ट होना चाहिए (यदि पारित नहीं है) " true" के रूप में ।

रूबी में यह लिखने का सबसे सरल तरीका होगा:

def name(use_email = true)
 # If firstname and surname are both blank (empty string or undefined)
 # and we can use the email...
 if (firstname.blank? && surname.blank?) && use_email
  # ... then, return the email
  return email
 else
  # ... else, concatenate the firstname and surname...
  name = "#{firstname} #{surname}"
  # ... and return the result striped from leading and trailing spaces
  return name.strip
 end
end

यह कोड इसे करने का तरीका समझने में सबसे सरल और आसान है। यहां तक ​​कि किसी के लिए जो रूबी को "नहीं" बोलते हैं।

आइए अब इसे छोटा बनाने की कोशिश करते हैं:

def name(use_email = true)
 # 'if' condition is used as a guard clause instead of a conditional block
 return email if (firstname.blank? && surname.blank?) && use_email
 # Use of 'return' makes 'else' useless anyway
 name = "#{firstname} #{surname}"
 return name.strip
end

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

अब इसे कमतर करने के लिए कुछ रूबी जादू का उपयोग करें:

def name(use_email = true)
 return email if (firstname.blank? && surname.blank?) && use_email
 # Ruby can return the last called value, making 'return' useless
 # and we can apply strip directly to our string, no need to store it
 "#{firstname} #{surname}".strip
end

यहां तक ​​कि दिशानिर्देशों को पूरी तरह से छोटा और अनुसरण करना ... लेकिन वापसी कथन की कमी के कारण बहुत कम स्पष्ट है, जो इस अभ्यास से अपरिचित लोगों के लिए थोड़ा भ्रमित करता है।

यह यहां है कि हम सवाल पूछना शुरू कर सकते हैं: क्या यह वास्तव में इसके लायक है? क्या हमें "नहीं, इसे पठनीय बनाना चाहिए और return" " जोड़ना चाहिए (यह जानते हुए कि यह दिशानिर्देशों का सम्मान नहीं करेगा)। या हमें कहना चाहिए "यह ठीक है, यह रूबी तरीका है, लानत भाषा सीखो!"

यदि हम विकल्प बी लेते हैं, तो इसे और भी छोटा क्यों न बनाएं:

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) || "#{firstname} #{surname}".strip
end

यहाँ यह है, एक लाइनर! बेशक यह कम है ... यहाँ हम इस तथ्य का लाभ उठाते हैं कि रूबी एक मान लौटाएगा या दूसरा जिसके आधार पर किसी को परिभाषित किया जाएगा (क्योंकि ईमेल को पहले की तरह उसी स्थिति में परिभाषित किया जाएगा)।

हम इसे भी लिख सकते हैं:

def name(use_email = true)
 (email if [firstname, surname].all?(&:blank?) && use_email) || "#{firstname} #{surname}".strip
end

यह छोटा है, पढ़ने में कठिन नहीं है (मेरा मतलब है, हम सभी ने देखा है कि एक बदसूरत वन-लाइनर कैसा दिख सकता है), अच्छा रूबी, यह मेरे द्वारा उपयोग किए जाने वाले दिशानिर्देश का अनुपालन करता है ... लेकिन फिर भी, लिखने के पहले तरीके की तुलना में यह, यह पढ़ने और समझने में बहुत आसान है। हम यह भी तर्क दे सकते हैं कि यह रेखा बहुत लंबी है (80 से अधिक अक्षर)।

सवाल

कोड के कुछ उदाहरण दिखा सकते हैं कि एक "पूर्ण-आकार" कोड और इसके कई कम संस्करणों (प्रसिद्ध वन-लाइनर के नीचे) के बीच चयन करना कठिन हो सकता है, क्योंकि हम देख सकते हैं, वन-लाइनर डरावना नहीं हो सकता है लेकिन फिर भी, कुछ भी पठनीयता के मामले में "पूर्ण-आकार" कोड को नहीं हराएगा ...

तो यहाँ असली सवाल है: कहाँ रुकना है? कब छोटा, काफी छोटा है? जब कोड "बहुत छोटा" और कम पठनीय हो (यह ध्यान में रखते हुए कि यह काफी व्यक्तिपरक है) कैसे पता चलेगा? और इससे भी अधिक: हमेशा तदनुसार कोड कैसे करें और कोड के "पूर्ण आकार" के साथ एक-लाइनर्स को मिश्रण करने से बचें जब मुझे बस ऐसा लगता है?

टी एल; डॉ

यहाँ मुख्य प्रश्न यह है: जब कोड के "लंबे, लेकिन स्पष्ट, पठनीय और समझने योग्य हिस्सा" और "शक्तिशाली, छोटी और मुश्किल से पढ़ने / समझने के लिए एक-लाइनर" के बीच चयन करने की बात आती है, तो उन दोनों को जानना सबसे ऊपर और एक स्केल के नीचे और न केवल दो विकल्प: कैसे परिभाषित करें कि "स्पष्ट रूप से पर्याप्त" और "जितना स्पष्ट होना चाहिए" के बीच सीमा कहां है? "

मुख्य प्रश्न शास्त्रीय "वन-लाइनर्स बनाम पठनीयता नहीं है: कौन सा बेहतर है?" लेकिन "उन दोनों के बीच संतुलन कैसे खोजें?"

संपादित करें 1

कोड के उदाहरणों में टिप्पणियों को "अनदेखा" करने के लिए है, वे यहां स्पष्ट करने के लिए हैं कि क्या हो रहा है, लेकिन कोड की पठनीयता का मूल्यांकन करते समय ध्यान में नहीं रखा जाता है।


7
एक उत्तर के लिए बहुत कम: जब तक आप यह सुनिश्चित नहीं कर लेते कि यह पिछले पुनरावृत्ति से बेहतर है, तब तक इसे रोकते रहें और अंतिम प्रतिक्षेपक को उलट दें।
डोम

8
मैं संस्करण 3 पसंद करते हैं के साथ returnकीवर्ड जोड़ा । मेरी नजर में उन सात पात्रों में काफी स्पष्टता है।
विस्फ़ोटक -

2
यदि आप वास्तव में भयानक महसूस कर रहे हैं, तो आप पूरी बात को इस प्रकार लिख सकते हैं [firstname,surname,!use_email].all?(&:blank?) ? email : "#{firstname} #{surname}".strip... क्योंकि false.blank?रिटर्न सही है और टर्नरी ऑपरेटर आपको कुछ अक्षर बचाता है ... characters \ _ (ツ) _ / ¯
डेवमॉन्गोज

1
ठीक है, मुझे पूछना है: returnकीवर्ड को जोड़ने के लिए क्या स्पष्टता है ?! यह कोई भी जानकारी प्रदान नहीं करता है । यह शुद्ध अव्यवस्था है।
कोनराड रुडोल्फ

2
स्पष्टता को स्पष्ट करने वाली धारणा न केवल घटते प्रतिफल के कानून से ग्रस्त है, बल्कि चरम सीमा पर पहुंचने पर उलट जाती है। यदि आप एक छोटे से कार्य को छोटा बनाने के लिए पुनर्लेखन कर रहे हैं, तो आप अपना समय बर्बाद कर रहे हैं, और अभ्यास को सही ठहराने की कोशिश कर रहे हैं।
सुधाम

जवाबों:


26

कोई फर्क नहीं पड़ता कि आप क्या कोड लिखते हैं, पठनीय सबसे अच्छा है। शॉर्ट दूसरा सबसे अच्छा है। और पठनीय का अर्थ आमतौर पर पर्याप्त रूप से कम होता है ताकि आप कोड, अच्छी तरह से पहचाने जाने वाले पहचानकर्ताओं, और उस भाषा के सामान्य मुहावरों का पालन कर सकें जिसमें कोड लिखा गया है।

यदि यह भाषा अज्ञेय थे, तो मुझे लगता है कि यह निश्चित रूप से राय-आधारित होगा, लेकिन रूबी भाषा की सीमाओं के भीतर मुझे लगता है कि हम इसका उत्तर दे सकते हैं।

सबसे पहले, रूबी लिखने की एक विशेषता और एक मुहावरेदार तरीका यह है कि returnमूल्य वापस करते समय कीवर्ड को छोड़ दिया जाए, जब तक कि किसी विधि से जल्दी वापस न आए।

ifकोड की पठनीयता बढ़ाने के लिए एक अन्य विशेषता और मुहावरा संयुक्त अनुगामी बयानों का उपयोग कर रहा है । रूबी में ड्राइविंग विचारों में से एक कोड लिखना है जो प्राकृतिक भाषा के रूप में पढ़ता है। इसके लिए, हम _why के मार्मिक गाइड रूबी, अध्याय 3 पर जाते हैं

अपने आप को निम्नलिखित जोर से पढ़ें।

5.times { print "Odelay!" }

अंग्रेजी वाक्यों में, विराम चिह्न (जैसे अवधि, विस्मयादिबोधक, कोष्ठक) चुप हैं। विराम चिह्नों को शब्दों में जोड़ा जाता है, यह संकेत देने में मदद करता है कि लेखक एक वाक्य से क्या चाहता है। तो चलिए उपरोक्त पढ़ते हैं: पांच बार "ओडेले!" प्रिंट करें।

इसे देखते हुए, रूबी के लिए कोड उदाहरण # 3 सबसे मुहावरेदार है:

def name(use_email = true)
  return email if firstname.blank? && surname.blank? && use_email

  "#{firstname} #{surname}".strip
end

अब जब हम कोड पढ़ते हैं, तो यह कहता है:

ई-मेल लौटाएं यदि पहला नाम रिक्त है, और उपनाम रिक्त है और ई-मेल का उपयोग करें

(वापसी) पहला नाम और अंतिम नाम छीन लिया गया

जो कि वास्तविक रूबी कोड के काफी सुंदर है।

यह वास्तविक कोड की केवल 2 पंक्तियाँ है, इसलिए यह बहुत ही सुंदर है, और यह भाषा के मुहावरों का पालन करती है।


अच्छी बात है। यह सच है कि सवाल रूबी-केंद्रित होने का नहीं था, लेकिन मैं इस बात से सहमत हूं कि यहां भाषा अज्ञेय का जवाब देना संभव नहीं है।
सुदुकिल

8
मुझे लगता है कि कोड की आवाज़ को प्राकृतिक भाषा की तरह बनाने का विचार बहुत हद तक (और कई बार समस्याग्रस्त भी है)। लेकिन इस प्रेरणा के बिना भी मैं इस जवाब के समान निष्कर्ष पर पहुंचता हूं।
कोनराड रुडोल्फ

1
एक और ट्वीक है जिसे मैं कोड पर विचार करूंगा। यही कारण है कि use_emailयह एक फ़ंक्शन कॉल के बजाय एक चर के बाद से अन्य शर्तों के सामने रखा गया है। लेकिन फिर से स्ट्रिंग प्रक्षेप में अंतर वैसे भी बदल जाता है।
जॉन ड्वोरक

प्राकृतिक भाषा संरचनाओं के बाद संरचना कोड आपको भाषा के जाल में पड़ सकता है। उदाहरण के लिए, जब आप अगली आवश्यकताओं को पढ़ते हैं, तो do send an email if A, B, C but no Dआपके आधार का अनुसरण करना स्वाभाविक होगा 2 टाइप करने के लिए यदि / अन्यथा ब्लॉक, जब शायद कोड करना आसान होगा if not D, send an email। प्राकृतिक भाषा को पढ़ने के क्षण में सावधान रहें और इसे कोड में रूपांतरित करें क्योंकि यह आपको "नित्य कहानी" का एक नया संस्करण लिख सकता है । कक्षाओं, विधियों और चर के साथ। सब के बाद एक बड़ी बात नहीं है।
Laiv

@ लिव: कोड को प्राकृतिक भाषा की तरह पढ़े जाने का मतलब यह नहीं है कि इसका अर्थ है आवश्यकताओं का अनुवाद करना। यह कोड लिखने का मतलब है ताकि जब जोर से पढ़ा जाए तो यह पाठक को हर बिट कोड, चरित्र के लिए चरित्र, भाषा के निर्माण के लिए भाषा निर्माण के बिना तर्क को समझने की अनुमति देता है। यदि यह कोडिंग if !Dबेहतर है, तो यह ठीक है जैसा कि Dएक सार्थक नाम है। और यदि !ऑपरेटर दूसरे कोड के बीच खो जाता है, तो एक पहचानकर्ता को बुलाया NotDजाना उचित होगा।
ग्रेग बर्गार्ड्ट

15

मुझे नहीं लगता कि आपको "अपने सर्वोत्तम निर्णय का उपयोग करने" की तुलना में बेहतर उत्तर मिलेगा। संक्षेप में आप के लिए प्रयास करना चाहिए स्पष्टता के बजाय तकलीफ । अक्सर, सबसे छोटा कोड भी सबसे स्पष्ट होता है, लेकिन अगर आप केवल लघुता को प्राप्त करने पर ध्यान केंद्रित करते हैं, तो नुकसान हो सकता है। यह स्पष्ट रूप से पिछले दो उदाहरणों में मामला है, जिसे पिछले तीन उदाहरणों की तुलना में समझने के लिए अधिक प्रयास की आवश्यकता है।

एक महत्वपूर्ण विचार कोड के दर्शक हैं। पठनीयता निश्चित रूप से पढ़ने वाले व्यक्ति पर पूरी तरह से निर्भर है। क्या आप जिन लोगों से (खुद के बगल में) कोड पढ़ने की उम्मीद करते हैं, वे वास्तव में रूबी भाषा के मुहावरों को जानते हैं? खैर यह सवाल इंटरनेट पर कुछ यादृच्छिक लोगों का जवाब नहीं है, यह केवल आपका अपना निर्णय है।


मैं दर्शकों की बात से सहमत हूं, लेकिन यह मेरे संघर्ष का हिस्सा है: जैसा कि मेरा सॉफ्टवेयर अक्सर खुला स्रोत है, दर्शकों को शुरुआती और साथ ही "रूबी देवताओं" द्वारा भी बनाया जा सकता है। मैं इसे ज्यादातर लोगों के लिए सुलभ बनाने के लिए इसे सरल रख सकता था, लेकिन यह थोड़े ही भाषा द्वारा पेश किए गए फायदों की बर्बादी जैसा लगता है।
सूदुकिल

1
जैसा कि किसी को अपने अधिकार में लेना, विस्तार करना और कुछ सही मायने में भयानक कोड को बनाए रखना है, स्पष्टता को जीतना है। पुरानी कहावत याद रखें - अपना कोड इस तरह लिखें जैसे कि अनुचर एक तामसिक नर्क की परी है जो जानता है कि आप कहाँ रहते हैं और आपके बच्चे स्कूल कहाँ जाते हैं।
uɐɪ

2
@ स्यूदुकिल: यह एक महत्वपूर्ण बिंदु है। मेरा सुझाव है कि आप उस स्थिति में मुहावरेदार कोड के लिए प्रयास करें (अर्थात भाषा का अच्छा ज्ञान ग्रहण करें), क्योंकि यह संभावना नहीं है कि शुरुआती वैसे भी स्रोत कोड खोलने में योगदान करेंगे। (या यदि वे ऐसा करते हैं, तो वे भाषा सीखने के प्रयास में
लगने के

7

यहाँ समस्या का एक हिस्सा "क्या पठनीयता है" है। मेरे लिए, मैं आपका पहला कोड उदाहरण देखता हूं:

def name(use_email = true)
 # If firstname and surname are both blank (empty string or undefined)
 # and we can use the email...
 if (firstname.blank? && surname.blank?) && use_email
  # ... then, return the email
  return email
 else
  # ... else, concatenate the firstname and surname...
  name = "#{firstname} #{surname}"
  # ... and return the result striped from leading and trailing spaces
  return name.strip
 end
end

और मुझे पढ़ना मुश्किल लगता है क्योंकि यह "शोर" टिप्पणियों से भरा है जो सिर्फ कोड दोहराते हैं। उन्हें बाहर निकालें:

def name(use_email = true)
 if (firstname.blank? && surname.blank?) && use_email
  return email
 else
  name = "#{firstname} #{surname}"
  return name.strip
 end
end

और यह अब इतना अधिक पठनीय है। फिर इसे पढ़ने में, मुझे लगता है कि "हम्म, मुझे आश्चर्य है कि अगर रूबी टर्नरी ऑपरेटर का समर्थन करता है? सी # में, मैं इसे प्राप्त कर सकता हूं:

string Name(bool useEmail = true) => 
    firstName.Blank() && surname.Blank() && useEmail 
    ? email 
    : $"{firstname} {surname}".Strip();

क्या माणिक में ऐसा कुछ संभव है? अपनी पोस्ट के माध्यम से काम करना, मुझे लगता है वहाँ है:

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) || "#{firstname} #{surname}".strip
end

सभी अच्छा सामान। लेकिन यह मेरे लिए पठनीय नहीं है; सिर्फ इसलिए कि मुझे पूरी लाइन देखने के लिए स्क्रॉल करना है। तो चलिए तय करते हैं कि:

def name(use_email = true)
 (email if (firstname.blank? && surname.blank?) && use_email) 
 || "#{firstname} #{surname}".strip
end

अब मैं खुश हूँ। मुझे पूरी तरह से यकीन नहीं है कि वाक्य रचना कैसे काम करती है, लेकिन मैं समझ सकता हूं कि कोड क्या करता है।

लेकिन वह सिर्फ मैं हूं। अन्य लोगों के पास कोड के टुकड़े को पढ़ने के लिए एक अच्छा विचार है। इसलिए आपको कोड लिखते समय अपने दर्शकों को जानना होगा। यदि आप एक शिक्षण निरपेक्ष शुरुआती हैं, तो आप इसे सरल रखना चाहते हैं और संभवतः इसे अपने पहले उदाहरण की तरह लिख सकते हैं। यदि आप कई वर्षों के रूबी अनुभव के साथ पेशेवर डेवलपर्स के एक सेट के बीच काम करते हैं, तो कोड लिखें जो भाषा का लाभ उठाता है और इसे छोटा रखता है। यदि यह बीच में कहीं है, तो बीच में कहीं के लिए लक्ष्य करें।

हालाँकि मैं एक बात कहूँगा: खबरदार "चतुर कोड", जैसे कि आपके अंतिम उदाहरण में। अपने आप से पूछें, क्या [firstname, surname].all?(&:blank?)आपको चतुर बनाने के अलावा कुछ और जोड़ता है क्योंकि यह आपके कौशल को दिखाता है, भले ही अब इसे पढ़ना थोड़ा कठिन हो? मैं कहूंगा कि यह उदाहरण उस श्रेणी में पूर्ण होने की संभावना है। यदि आप पांच मूल्यों की तुलना कर रहे हैं, तो मैं इसे एक अच्छे कोड के रूप में देखूंगा। तो फिर, यहाँ कोई निरपेक्ष रेखा नहीं है, बस बहुत चालाक होने का ध्यान रखें।

इसलिए संक्षेप में: पठनीयता के लिए आपको अपने दर्शकों को जानना होगा और तदनुसार अपने कोड को लक्षित करना होगा और रसीद लिखना होगा, लेकिन स्पष्ट कोड; कभी भी "चतुर" कोड न लिखें। इसे छोटा रखें, लेकिन बहुत कम नहीं।


2
खैर, मैं इसका उल्लेख करना भूल गया, लेकिन टिप्पणियों को "अनदेखा" करने के लिए किया गया था, वे यहां केवल उन लोगों की मदद करने के लिए हैं जो रूबी को अच्छी तरह से नहीं जानते हैं। दर्शकों के बारे में मान्य बिंदु, मैंने उसके बारे में नहीं सोचा था। जैसा कि उस संस्करण के लिए जो आपको खुश करता है: यदि यह लाइन की लंबाई है जो मायने रखती है, तो मेरे कोड का तीसरा संस्करण (केवल एक रिटर्न स्टेटमेंट के साथ) थोड़े ऐसा करता है और यहां तक ​​कि थोड़ा अधिक समझ में आता है, नहीं?
सुदुकिल

1
@ स्यूदुकिल, एक रूबी डेवलपर नहीं होने के कारण, मैंने पाया कि पढ़ने में सबसे कठिन और यह फिट नहीं था जो मैं (सर्वश्रेष्ठ भाषा के परिप्रेक्ष्य से) "सर्वश्रेष्ठ" समाधान के रूप में देख रहा था। हालांकि, इस तथ्य से परिचित किसी के लिए कि माणिक उन भाषाओं में से एक है जो अंतिम अभिव्यक्ति का मूल्य लौटाता है, यह संभावना सबसे सरल, सबसे आसान संस्करण का प्रतिनिधित्व करता है। फिर, यह आपके दर्शकों के बारे में है।
डेविड अरनो

रूबी डेवलपर नहीं है, लेकिन यह मेरे लिए शीर्ष-वोट किए गए उत्तर की तुलना में बहुत अधिक समझ में आता है, जो पढ़ता है कि "यहां वह है जो मैं लौटने जा रहा हूं [फुटनोट: एक विशिष्ट लंबी स्थिति के तहत]। इसके अलावा, यहां एक स्ट्रिंग है जो देर से आई। पार्टी को।" लॉजिक जो अनिवार्य रूप से सिर्फ एक केस स्टेटमेंट है, एक ही यूनिफॉर्म केस स्टेटमेंट की तरह लिखा जाना चाहिए, एक से अधिक असंबद्ध बयानों में नहीं फैलता।
पॉल

व्यक्तिगत रूप से मैं आपके दूसरे कोड ब्लॉक के साथ जाऊंगा, सिवाय इसके कि मैं दो बयानों को आपकी शाखा में एक दूसरे में जोड़ return "#{firstname} #{surname}".strip
पॉल

2

यह शायद एक सवाल है जहां एक राय-आधारित जवाब देना मुश्किल नहीं है, लेकिन, यहां मेरे दो सेंट हैं।

यदि आप पाते हैं कि कोड को कम करने से पठनीयता प्रभावित नहीं होती है, या यहां तक ​​कि इसमें सुधार होता है, तो इसके लिए जाएं। यदि कोड कम पठनीय हो जाता है, तो आपको यह विचार करने की आवश्यकता है कि क्या इस तरह से छोड़ने का एक अच्छा कारण है। ऐसा करना सिर्फ इसलिए कि यह छोटा है, या ठंडा है, या सिर्फ इसलिए कि आप कर सकते हैं, बुरे कारणों के उदाहरण हैं। आपको यह विचार करने की भी आवश्यकता है कि क्या कोड को कम करने से यह आपके साथ काम करने वाले अन्य लोगों के लिए कम समझ में आएगा।

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


1

इसका उत्तर थोड़ा व्यक्तिपरक है, लेकिन आपको अपने आप से पूरी ईमानदारी के साथ पूछना होगा जो आप कर सकते हैं, यदि आप उस कोड को एक या दो महीने में वापस आने पर समझ पाएंगे।

प्रत्येक परिवर्तन को कोड को समझने के लिए औसत व्यक्ति की क्षमता में सुधार होना चाहिए। कोड को समझने योग्य बनाने के लिए, यह निम्नलिखित दिशानिर्देशों का उपयोग करने में मदद करता है:

  • भाषा के मुहावरों का सम्मान करें । C #, जावा, रूबी, पायथन सभी के पास एक ही काम करने के अपने पसंदीदा तरीके हैं। मुहावरेदार निर्माण उस कोड को समझने में मदद करते हैं जिससे आप परिचित नहीं हैं।
  • जब आपका कोड कम पठनीय हो जाए तो रुक जाएं । आपके द्वारा प्रदान किए गए उदाहरण में, यह तब हुआ जब आपने कोड को कम करने के अपने अंतिम जोड़े को मारा। आपने पिछले उदाहरण का मुहावरेदार लाभ खो दिया है, और बहुत सारे प्रतीकों को पेश किया है जिन्हें वास्तव में समझने के लिए बहुत सोच की आवश्यकता है कि क्या हो रहा है।
  • केवल टिप्पणियों का उपयोग करें जब आपको कुछ अप्रत्याशित को सही ठहराना हो । मुझे पता है कि रूबी से कम परिचित लोगों को निर्माण समझाने के लिए आपके उदाहरण थे, और यह एक प्रश्न के लिए ठीक है। मैं अप्रत्याशित व्यावसायिक नियमों की व्याख्या करने के लिए टिप्पणियों का उपयोग करना पसंद करता हूं, और यदि कोड खुद के लिए बोल सकता है तो उनसे बचें।

कहा कि, ऐसे समय होते हैं जहां विस्तारित कोड यह समझने में मदद करता है कि बेहतर क्या हो रहा है। इसके साथ एक उदाहरण C # और LINQ से आता है। LINQ एक बेहतरीन टूल है और कुछ स्थितियों में पठनीयता बढ़ा सकता है, लेकिन मैंने कई परिस्थितियों में भी भाग लिया है जहाँ यह बहुत अधिक भ्रमित करने वाला था। मुझे सहकर्मी की समीक्षा में कुछ प्रतिक्रिया मिली है, जिसने सुझाव के साथ अभिव्यक्ति को लूप में बदलने का सुझाव दिया है, ताकि अन्य लोग इसे बेहतर बनाए रख सकें। जब मैंने अनुपालन किया, तो वे सही थे। तकनीकी रूप से, LINQ C # के लिए अधिक मुहावरेदार है, लेकिन ऐसे मामले हैं जहां यह समझ में कमी आती है और एक अधिक क्रिया समाधान इसे बेहतर बनाता है।

मैं यह कहने के लिए वह सब कहता हूं:

जब आप अपने कोड को बेहतर बना सकते हैं तो सुधार करें (अधिक समझने योग्य)

याद रखें, आपको या आपके जैसे किसी व्यक्ति को बाद में उस कोड को बनाए रखना होगा। अगली बार जब आप इसके पार आएंगे तो लाइन में महीनों लग सकते हैं। अपने आप को एक एहसान करो और अपने कोड को समझने में सक्षम होने की कीमत पर लाइन को कम करने का पीछा मत करो।


0

पठनीयता एक संपत्ति है जिसे आप रखना चाहते हैं, कई-एक-लाइनर नहीं है। इसलिए "वन-लाइनर्स बनाम पठनीयता" के बजाय सवाल यह होना चाहिए:

वन-लाइनर्स पठनीयता कब बढ़ाते हैं, और वे इसे कब नुकसान पहुंचाते हैं?

मेरा मानना ​​है कि वन-लाइनर्स पठनीयता के लिए अच्छे हैं जब वे इन दो शर्तों को पूरा करते हैं:

  1. वे एक समारोह में निकाले जाने के लिए बहुत विशिष्ट हैं।
  2. आप आसपास के कोड को पढ़ने के "प्रवाह" को बाधित नहीं करना चाहते हैं।

उदाहरण के लिए, मान लें कि nameआपकी विधि के लिए एक अच्छा ... नाम नहीं था। पहला नाम और उपनाम का संयोजन, या नाम के बजाय ईमेल का उपयोग करना, प्राकृतिक चीजें नहीं थीं। तो nameसबसे अच्छी बात के बजाय आप लंबे और बोझिल हो सकते हैं:

puts "Name: #{user.email_if_there_is_no_name_otherwise_use_firstname_and_surname(use_email)}"

ऐसा लंबा नाम इंगित करता है कि यह बहुत विशिष्ट है - यदि यह अधिक सामान्य था तो आपको अधिक सामान्य नाम मिल सकता था। इसलिए इसे एक विधि में लपेटने से न तो पठनीयता (यह बहुत लंबा है) और न ही DRYness (बहुत विशिष्ट कहीं और उपयोग किए जाने के लिए) के साथ मदद नहीं करता है, इसलिए बेहतर होगा कि कोड को वहीं छोड़ दें।

फिर भी - इसे वन-लाइनर क्यों बनाया जाए? वे आमतौर पर मल्टीलाइन कोड से कम पठनीय होते हैं। यह वह जगह है जहां हमें अपनी दूसरी स्थिति की जांच करनी चाहिए - आसपास के कोड का प्रवाह। अगर आपके पास ऐसा कुछ है तो:

puts "Group: #{user.group}"
puts "Title: #{user.title}"
if user.firstname.blank? && user.surname.blank?) && use_email
  name = email
else
  name = "#{firstname} #{surname}"
  name.strip
end
puts "Name: #{name}"
puts "Age: #{user.age}"
puts "Address: #{user.address}"

मल्टीलाइन कोड स्वयं पठनीय है - लेकिन जब आप आसपास के कोड (विभिन्न क्षेत्रों को प्रिंट करते हुए) को पढ़ने की कोशिश करते हैं, तो मल्टीलाइन निर्माण प्रवाह को बाधित कर रहा है। यह पढ़ना आसान है:

puts "Group: #{user.group}"
puts "Title: #{user.title}"
puts "Name: #{(email if (user.firstname.blank? && user.surname.blank?) && use_email) || "#{user.firstname} #{user.surname}".strip}"
puts "Age: #{user.age}"
puts "Address: #{user.address}"

आपके प्रवाह में रुकावट नहीं आती है, और यदि आपको ज़रूरत है तो आप विशिष्ट अभिव्यक्ति पर ध्यान केंद्रित कर सकते हैं।

क्या यह आपका मामला है? निश्चित रूप से नहीं!

पहली स्थिति कम प्रासंगिक है - आपने पहले से ही इसे विधि के लायक होने के लिए सामान्य रूप से पर्याप्त समझा, और उस पद्धति के लिए एक नाम के साथ आया जो इसे लागू करने की तुलना में बहुत अधिक पठनीय है। जाहिर है आप इसे फिर से एक समारोह में नहीं निकालेंगे।

दूसरी शर्त के रूप में - क्या यह आसपास के कोड के प्रवाह को बाधित करता है? नहीं! आस-पास का कोड एक विधि घोषणा है, कि nameइसे चुनना एकमात्र उद्देश्य है। नाम चुनने का तर्क आसपास के कोड के प्रवाह को बाधित नहीं कर रहा है - यह आसपास के कोड का बहुत उद्देश्य है!

निष्कर्ष - संपूर्ण फ़ंक्शन बॉडी को वन-लाइनर न बनाएं

एक-लाइनर अच्छा है जब आप प्रवाह को बाधित किए बिना कुछ जटिल करना चाहते हैं। एक फ़ंक्शन घोषणा पहले से ही प्रवाह को बाधित कर रही है (ताकि जब आप उस फ़ंक्शन को कॉल करते हैं तो यह बाधित नहीं होगा), इसलिए पूरे फ़ंक्शन को एक-लाइनर बनाने से पठनीयता में मदद नहीं मिल रही है।

ध्यान दें

मैं "पूर्ण विकसित" फ़ंक्शन और विधियों का उल्लेख कर रहा हूं - इनलाइन फ़ंक्शंस या लैम्ब्डा एक्सप्रेशन नहीं जो आमतौर पर आसपास के कोड का हिस्सा होते हैं और इसके प्रवाह के भीतर फिट होने की आवश्यकता होती है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.