2009-06-21 5 views
116

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

क्या यह "रूबी वे" स्पष्ट रूप से return को विधियों में टाइप करने के लिए है? मैंने इसे बिना और बिना देखा है, लेकिन क्या ऐसा करने का कोई सही तरीका है? क्या ऐसा करने के लिए शायद समय है? उदाहरण के लिए:

def some_func(arg1, arg2, etc) 
    # Do some stuff... 
    return value # <-- Is the 'return' needed here? 
end 
+1

यह एक बहुत पुराना सवाल है, लेकिन जिनके पास समान प्रश्न हैं, उनके लिए पुस्तक Eloquent रूबी की अत्यधिक अनुशंसा की जाती है। यह मूर्खतापूर्ण रूबी लिखने के परिचय के रूप में एक स्टाइल गाइड नहीं है। मेरी इच्छा है कि लोग इसे पढ़ लेंगे! –

उत्तर

181

पुराना (और "उत्तर दिया गया) प्रश्न, लेकिन मैं अपने दो सेंट में जवाब के रूप में टॉस करूंगा।

टीएल; डीआर - आपको नहीं करना है, लेकिन यह कुछ मामलों में आपके कोड को और अधिक स्पष्ट कर सकता है।

हालांकि एक स्पष्ट वापसी का उपयोग नहीं करना "रूबी रास्ता" हो सकता है, यह अपरिचित कोड के साथ काम कर रहे प्रोग्रामर को भ्रमित कर रहा है, या रूबी की इस सुविधा से अपरिचित है।

उदाहरण के लिए किसी के पास इस तरह का एक छोटा सा फ़ंक्शन हो सकता है, जो पारित संख्या में एक जोड़ता है, और इसे एक आवृत्ति चर में निर्दिष्ट करता है।

def plus_one_to_y(x) 
    @y = x + 1 
end 

इस एक समारोह है कि एक मान दिया, या नहीं जाना चाहिए था? यह कहना मुश्किल है कि डेवलपर का क्या अर्थ था, क्योंकि यह दोनों आवृत्ति चर निर्दिष्ट करता है, और साथ ही मूल्य को भी देता है।

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

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
end 

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

असली सवाल यह है: क्या कुछ भी वास्तव में लौटाए गए मूल्य की अपेक्षा करता है? क्या यह कुछ तोड़ दिया या नहीं? क्या यह भविष्य में कुछ तोड़ देगा? कौन जाने! सभी कॉलों की केवल एक पूर्ण कोड समीक्षा आपको बताएगी।

तो मेरे लिए कम से कम, सबसे अच्छा अभ्यास दृष्टिकोण या तो बहुत स्पष्ट होना है कि यदि आप मायने रखते हैं तो आप कुछ वापस कर रहे हैं, या कुछ भी वापस नहीं कर सकते हैं।

हमारी छोटी सी डेमो समारोह के मामले में

तो, यह सोचते हैं कि हम इसे एक मूल्य के वापस जाने के लिए चाहता था, तो वह ऐसा लिखा जाएगा ...

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
    return @y 
end 

और यह किसी भी प्रोग्रामर करने के लिए बहुत स्पष्ट हो जाएगा यह है कि एक मूल्य वापस करता है, और इसे महसूस किए बिना इसे तोड़ने के लिए बहुत कठिन है।

वैकल्पिक रूप से, एक यह इस प्रकार लिख सकते और वापसी कथन बाहर छोड़ ...

def plus_one_to_y(x) 
    @y = x + 1 
    puts "In plus_one_to_y" 
    @y 
end 

लेकिन शब्द वापसी बाहर छोड़ने परेशान? क्यों न सिर्फ इसे वहां रखें और 100% स्पष्ट करें कि क्या हो रहा है? इसका सचमुच आपके कोड की प्रदर्शन करने की क्षमता पर कोई असर नहीं पड़ेगा।

+5

क्यों दिलचस्प बिंदु के लिए नीचे मेरा उत्तर देखें। मुझे लगता है कि मैं वास्तव में इसी तरह की स्थिति में भाग गया जब मैंने इस सवाल से पूछा, जहां मूल डेवलपर ने अपने कोड में अंतर्निहित वापसी मूल्य का उपयोग किया था, और यह समझना बहुत मुश्किल था कि क्या हो रहा था। आपके उत्तर के लिए धन्यवाद! –

+5

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

+14

सच है, कोड को पढ़ने योग्य के लिए महत्वपूर्ण है, वर्बसिटी के पक्ष में प्रोग्रामिंग भाषा की एक प्रसिद्ध विशेषता को छोड़कर, मेरी राय में, बुरी आदत है। यदि कोई डेवलपर रूबी से परिचित नहीं है, तो शायद कोड को छूने से पहले उन्हें परिचित होना चाहिए। मुझे लगता है कि भविष्य में होने वाली घटना के लिए मेरे कोड के अव्यवस्था को बढ़ाने के लिए मुझे कुछ मूर्खतापूर्ण लगता है कि कुछ गैर-रूबी डेवलपर को बाद में कुछ करना है। हमें सबसे कम आम denominator के लिए एक भाषा को कम नहीं करना चाहिए। रुबी की सुंदरता का एक हिस्सा यह है कि हमें कुछ ऐसा करने के लिए कोड की 5 लाइनों का उपयोग करने की ज़रूरत नहीं है जो केवल 3 लेना चाहिए। –

62

सं अच्छा रूबी शैली आम तौर पर केवल एक जल्दी वापसी के लिए एक स्पष्ट रिटर्न का प्रयोग करेंगे। रूबी कोड minimalism/implicit जादू पर बड़ा है।

उसने कहा, यदि एक स्पष्ट वापसी चीजों को स्पष्ट या पढ़ने में आसान बनाती है, तो इससे कुछ भी नुकसान नहीं पहुंचाएगा।

+80

कोड minimal minimalism का बिंदु क्या है यदि यह भ्रम अधिकतमता में परिणाम होता है? – jononomo

+0

@ जोनक्रॉवेल इसके बजाय दस्तावेज़ीकरण अधिकतमता में परिणाम होना चाहिए। – jazzpi

+21

@jazzpi यदि आपको इसके कोड को भारी रूप से समझना है कि आप कम से कम समझ रहे हैं, तो आप [कोड गोल्फ] (https://en.wikipedia.org/wiki/Code_golf) का अभ्यास कर रहे हैं। – Schwern

0

बेन की तरह। तथ्य यह है कि 'रूबी विधि का रिटर्न वैल्यू फ़ंक्शन बॉडी में अंतिम कथन का रिटर्न वैल्यू' होता है, जिसके कारण अधिकांश रूबी विधियों में रिटर्न कीवर्ड का शायद ही कभी उपयोग किया जाता है।

def some_func_which_returns_a_list(x, y, z) 
    return nil if failed_some_early_check 


    # function code 

    @list  # returns the list 
end 
+4

यदि आप अपना इरादा अभी भी स्पष्ट हैं –

+0

यह मान्य कोड नहीं है, तो जवाब को भ्रमित करने के लिए यह वैध कोड नहीं है, तो आप "वापसी शून्य अगर विफल_some_early_check" लिख सकते हैं। –

+0

@Andew - फिक्स्ड। उम्मीद है कि अब आपके लिए काम करता है। – Gishu

1

यह सबसे महत्वपूर्ण बात है कि आप किस शैली को पसंद करते हैं। यदि आप किसी विधि के बीच में कहीं से वापस लौटना चाहते हैं तो आपको कीवर्ड रिटर्न का उपयोग करना होगा।

30

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

मैं उसी भेद का उपयोग करता हूं जब कॉलिंग को कॉल करता है: कार्यात्मक तरीके कोष्ठक मिलते हैं, प्रक्रियात्मक तरीके नहीं होते हैं।

और अंत में कम से कम, मैं भी ब्लॉक के साथ उस भेद का उपयोग करें: कार्यात्मक ब्लॉक घुंघराले ब्रेसिज़, प्रक्रियात्मक ब्लॉक (अर्थात ब्लॉक है कि कुछ "do") do/end मिल मिलता है।

हालांकि, मैं इसके बारे में धार्मिक होने के लिए नहीं की कोशिश: ब्लॉक, घुंघराले ब्रेसिज़ और do/end के साथ विभिन्न पूर्वता है, और नहीं बल्कि एक अभिव्यक्ति को स्पष्ट करने के लिए स्पष्ट कोष्ठकों जोड़ने से, मैं सिर्फ अन्य शैली में स्विच करें। विधि कॉलिंग के लिए भी यही होता है: यदि पैरामीटर सूची के चारों ओर कोष्ठक जोड़ना कोड को और अधिक पठनीय बनाता है, तो मैं ऐसा करता हूं, भले ही प्रश्न में विधि प्रकृति में प्रक्रियात्मक हो।

+1

अभी मैं किसी भी "एक-लाइनर" में वापसी छोड़ देता हूं, जो आप जो कर रहे हैं उसके समान है, और मैं सब कुछ वही करता हूं। जानना अच्छा है कि मैं अपनी शैली में पूरी तरह से बंद नहीं हूं। :) –

+0

@ जोर्ग: क्या आप अपने कोड में शुरुआती रिटर्न का उपयोग करते हैं? क्या इससे आपकी प्रक्रियात्मक/कार्यात्मक योजना के साथ कोई भ्रम पैदा होता है? –

+1

@ एंड्रयू ग्रिम: हाँ, और हां। मैं इसे बदलने की सोच रहा हूं। मेरे तरीकों का विशाल बहुमत संदर्भित रूप से पारदर्शी/शुद्ध/कार्यात्मक/जो भी आप इसे कॉल करना चाहते हैं, इसलिए वहां छोटे फॉर्म का उपयोग करना समझ में आता है। और कार्यात्मक शैली में लिखे गए तरीकों में प्रारंभिक रिटर्न नहीं होते हैं, क्योंकि यह "चरण" की धारणा का तात्पर्य है, जो बहुत कार्यात्मक नहीं है। हालांकि, मुझे बीच में रिटर्न पसंद नहीं है। मैं या तो शुरुआत में उन्हें गार्ड के रूप में या अंत में नियंत्रण प्रवाह को सरल बनाने के लिए उपयोग करता हूं। –

13

वास्तव में महत्वपूर्ण बात यह है के बीच अंतर करना है:

  1. कार्य - उनकी वापसी मूल्य
  2. प्रक्रिया के लिए मार डाला तरीकों - उनके साइड इफेक्ट के लिए मार डाला तरीकों

रूबी एक देशी नहीं है इन्हें अलग करने का तरीका - जो आपको एक प्रक्रिया side_effect() लिखने के लिए कमजोर बनाता है और एक अन्य डेवलपर आपकी प्रक्रिया के अंतर्निहित वापसी मूल्य का दुरुपयोग करने का निर्णय लेता है (मूल रूप से इसे एक अशुद्ध कार्य के रूप में व्यवहार करता है)।

इस को हल करने के स्काला और हास्केल की किताब के बाहर एक पत्ती लेने के लिए और अपने प्रक्रियाओं स्पष्ट रूप से लौट nil (उर्फ Unit या () अन्य भाषाओं में) है।

यदि आप इसका पालन करते हैं, तो स्पष्ट return वाक्यविन्यास का उपयोग करना या न केवल व्यक्तिगत शैली का मामला बन जाता है।

    do/end
  1. जब आप प्रक्रियाओं आह्वान के साथ घुंघराले ब्रेसिज़, और प्रक्रियात्मक ब्लॉक के साथ कार्यात्मक ब्लॉक लिखने की
  2. कॉपी जोर्ग डब्ल्यू Mittag के अच्छा विचार है, () उपयोग करते हैं, जबकि जब:

    आगे कार्यों और प्रक्रियाओं के बीच अंतर करने के लिए आप कार्यों आह्वान, ऐसा नहीं

ध्यान दें कि जोर्ग डब्ल्यू Mittag वास्तव में दूसरी तरह के आसपास की वकालत - परहेज प्रक्रियाओं के लिए () रों - लेकिन यह है कि विज्ञापन नहीं है दृश्यमान क्योंकि आप साइड इफेक्टिंग विधि आविष्कार चाहते हैं वे चर से स्पष्ट रूप से भिन्न हो सकते हैं, खासकर जब arity 0 है। विवरण के लिए Scala style guide on method invocation देखें।

+0

कोड कर सकते हैं यदि मुझे 'function_a' से लौटाए गए मान की आवश्यकता है, और' function_a' को कॉल करने के लिए लिखा गया था (और केवल कॉल करके ही संचालित हो सकता है) 'process_b', तो' function_a 'है वास्तव में एक समारोह? यह एक मूल्य देता है, कार्यों के लिए आपकी आवश्यकता को पूरा करता है, लेकिन इसकी प्रक्रियाओं की आवश्यकताओं को पूरा करते हुए इसका दुष्प्रभाव होता है। –

+2

आप सही हैं डेवन - 'function_a' में 'प्रक्रिया _...' का पेड़ हो सकता है, क्योंकि वास्तव में 'process_a' में' फंक्शन _.. 'कॉल का पेड़ हो सकता है। स्काला की तरह, लेकिन हास्केल के विपरीत, रुबी में कोई गारंटी नहीं हो सकती है कि एक समारोह साइड-इफेक्टिंग नहीं है। –

3

मैं बेन ह्यूजेस से सहमत हूं और टिम होल्ट से असहमत हूं, क्योंकि प्रश्न में पाइथन ऐसा निश्चित तरीका बताता है और पूछता है कि रूबी का एक समान मानक है या नहीं।

It does.

इस भाषा कि रूबी में एक समस्या डिबग करने की उम्मीद किसी को भी यथोचित इसके बारे में पता करने के लिए उम्मीद की जानी चाहिए की इस तरह के एक जाने-माने सुविधा है।

+2

मैं सिद्धांत में आपके साथ सहमत हूं, लेकिन व्यवहार में, प्रोग्रामर गलतियां करते हैं और गड़बड़ करते हैं। बिंदु में मामला, हम सभी जानते हैं कि आप एक सशर्त में "==" का उपयोग करते हैं, न कि "=", लेकिन हम सभी ने पहले ही गलती की है और इसे बाद में महसूस नहीं किया है। –

+1

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

+2

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

7

The style guide राज्यों, कि आपको अपने अंतिम वक्तव्य पर return का उपयोग नहीं करना चाहिए। आप अभी भी if it's not the last one का उपयोग कर सकते हैं। यह उन सम्मेलनों में से एक है जो समुदाय सख्ती से पालन करता है, और यदि आप रूबी का उपयोग करके किसी के साथ सहयोग करने की योजना बनाते हैं तो आपको भी ऐसा करना चाहिए।


कहा जा रहा है, स्पष्ट return रों प्रयोग करने के लिए मुख्य तर्क है कि यह अन्य भाषाओं से आने वाले लोगों के लिए भ्रामक है है।

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

जावा में विधि लंबाई (छोड़कर getters/setters) के लिए एक आम अनुमानी एक स्क्रीन है। उस स्थिति में, हो सकता है कि आप विधि परिभाषा नहीं देख रहे हों और/या पहले से ही भूल गए हैं कि आप कहां से लौट रहे थे।

दूसरी ओर, रूबी में less than 10 lines long विधियों के साथ रहना सर्वोत्तम होता है। यह देखते हुए कि, कोई आश्चर्यचकित होगा कि उन्हें स्पष्ट रूप से निहित होने पर ~ 10% अधिक वक्तव्य क्यों लिखना है।


के बाद रूबी शून्य विधियां नहीं हैं और सब कुछ है कि बहुत अधिक संक्षिप्त, तो आप सिर्फ भूमि के ऊपर लाभ से कोई भी के लिए जोड़ रहे हैं, तो आप स्पष्ट return रों के साथ जाना है।

+0

_ "यह उन सम्मेलनों में से एक है जो समुदाय सख्ती से पालन करता है" _ मेरा अनुभव यह है कि नहीं, लोग सख्ती से इसका पालन नहीं करते हैं जब तक वे रूबी डेवलपर्स का अनुभव नहीं करते हैं। –

+0

@ टिमहोल्ट मैं तब बहुत भाग्यशाली रहा होगा। (: – ndn

+0

मैं तर्क दूंगा कि रूबीवादियों को सैंडी के नियमों का पालन करना चाहिए - 100 से अधिक लाइनों की कक्षाएं, 5 से अधिक विधियों, विधि में 4 से अधिक पैराम पास नहीं हुए हैं। –

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