2017-01-07 4 views
8

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

foo = bar[:a][:b][:c] rescue nil

के लिए लेकिन क्योंकि मुझे इसकी आपरिवर्तक के रूप में बचाव का उपयोग कर व्यवहार में मुझे बुरा शैली बताओ। मैं चेक तीन स्थिति का उपयोग करने के लिए तर्क बदल जाएगा।

foo = bar[:a][:b][:c] if bar.key?(:a) && bar[:a].key?(:b) && bar[:a][:b].key?(:c)

मैं वास्तव में पता करने के लिए हम पटरियों में अपनी आपरिवर्तक के रूप में बचाव का उपयोग कर से क्यों बचना चाहिए चाहते हैं?

+1

यह ध्यान देने योग्य है कि यह खराब शैली है, इसके लिए वैध उपयोग हैं। –

उत्तर

14

हमें रेल में अपने संशोधक रूप में बचाव का उपयोग क्यों करना चाहिए?

सबसे पहले

, क्योंकि यह खाल जिन्हें आप उम्मीद करते हैं और जिन्हें आप नहीं करते हैं, और एक कंबल rescue यह आपके कोड जो त्रुटियां होने के भविष्य के पाठकों के लिए स्पष्ट नहीं है सहित सभी त्रुटियों, अपेक्षित या अप्रत्याशित। यह एक समस्या अब नहीं हो सकता है, एक सरल foo[:a][:b][:c] साथ है, लेकिन समय किसी में कोई भी बिंदु पर है कि कथन को संशोधित हो सकता है कि some_method से बाहर बुलबुला भी निगल लिया जाना चाहिए foo[:a][:b][some_method] और अचानक किसी भी त्रुटि को पढ़ने के लिए।

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

आपके मामले में, विकल्प भारी if && && && है जो आप सुझाव दे रहे हैं। एक हैश के लिए, आप अपवाद के हर प्रकार है कि उठाया जा सकता है निगलने के बिना जो rescue के सभी फायदे हैं या तो dig उपयोग कर सकते हैं,:

foo = bar.dig(:a, :b, :c) 

इसी तरह, श्रृंखलित विधि आमंत्रण के लिए, आप (रेल में) try उपयोग कर सकते हैं (रूबी 2.3 में) या सुरक्षित नेविगेशन ऑपरेटर:

foo = bar.try(:a).try(:b).try(:c) 
# or 
foo = bar&.a&.b&.c 
+0

आईएमएचओ यह ध्यान देने योग्य है कि अपवाद उठाना एक बहुत ही महंगी ऑपरेशन है। विकल्पों में से किसी एक का उपयोग करके 'शून्य' लौटने का आमतौर पर उन मामलों में तेज़ तरीका होता है जिनमें एक कुंजी मौजूद नहीं होती है। – spickermann

0

कारण है कि यह एक बुरा विचार है के रूप में एक विशिष्ट उदाहरण:

foo = ban[:a][:b][:c] rescue nil 

आप bar में वास्तव में {a: {b: {c: :something}}} की जांच कर रहे हैं और foonilnil है: एक टाइपो है, और rescue nil इसे छुपाता है।

विकल्पों के लिए, @ मेगर का अच्छा जवाब देखें।

1

बचें

... rescue ... 
इसी कारण

रूप

begin 
    ... 
rescue 
    ... 
end 

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

अपवाद बनाने के लिए भी एक बड़ी लागत है।

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

इसलिए जब संभव विकल्पों कि अपवाद

foo = bar.dig(:a, :b, :c) 
3

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

begin 
    # - 
    raise "another exception" 
rescue SyntaxError 
    # - 
rescue => exception 
    @errors += 1 
    log exception 
    log exception.backtrace 
end 

कौन सा

another exception 
C:/.../test.rb:3:in `<main>' 

हमेशा अपवाद की तरह बेहतर पकड़ने और डाल या लॉग यह देता है, मैं भी इसका इस्तेमाल एक चर @errors जो मेरे लिपियों के सभी के लिए लॉग इन और एक अलग से निगरानी रखी जाती है बढ़ाने के लिए उपकरण।

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