2012-11-07 6 views
16

मैं कभी-कभी begin...end ब्लू में किसी भी rescue, else, ensure, आदि के बिना बयान में उपयोग किए गए ब्लॉक देखता हूं। उदाहरण के लिए:रुबी के 'प्रारंभ ... अंत' के बिना कोड बचाव के रूप में इस्तेमाल किए गए 'बचाव' के अनपेक्षित परिणाम हैं?

foo = begin 
    whatever = 3 
    "great" 
    42 
end 

सांकेतिक शब्दों में बदलनेवाला की मंशा, ऐसा लगता है, बस इसके ब्लॉक समूहीकरण गुणवत्ता के लिए begin...end ब्लॉक का उपयोग करने के लिए है (जैसे कि begindo थे)। व्यक्तिगत रूप से मुझे लगता है कि इस उपयोग की तरह कम से कम आश्चर्य के सिद्धांत का उल्लंघन करती है (begin मुझे अपवाद-प्रबंधन का तात्पर्य है)।

क्या इस तरह से begin...end का उपयोग करने के कोई अनपेक्षित परिणाम हैं? क्या begin...end ब्लॉक में कोई अर्थपूर्ण मतभेद है (शायद अपवाद-हैंडलिंग में?) जो इस उपयोग को खतरनाक बनाता है?

रुबी का वाक्यविन्यास अविश्वसनीय रूप से सूक्ष्म है, और अगर मैं यहां इंतजार में अजीब गेटचास झूठ बोल रहा था तो मुझे आश्चर्य नहीं होगा।

+0

मैंने कभी इस तरह कोड नहीं देखा है। क्या आप सार्वजनिक स्रोत फ़ाइल पर इंगित कर सकते हैं? –

+0

@SergioTulentsev: जब तक मैं एक स्रोत फ़ाइल नहीं ढूंढ पाता, यहां एक ब्लॉग टिप्पणी है: http://blog.rubybestpractices.com/posts/rklemme/003-The_Universe_between_begin_and_end।एचटीएमएल # टिप्पणी -9011441 – pje

+0

मुझे नहीं पता कि यह खतरनाक कैसे होगा, लेकिन आईएमओ यह गलत है: यह एक विधि होनी चाहिए। –

उत्तर

27

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

if @cache.nil? 
    do_something! 
    @cache = read_value 
end 

की तो बजाय है आप क्या कर सकते हैं

@cache ||= begin 
    do_something! 
    read_value 
end 

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

मुझे नहीं लगता कि यह कम से कम आश्चर्य का उल्लंघन करता है, मुझे लगता है कि यह उपयोगकर्ता वरीयता पहिया है जिसका आप इसका उपयोग करना चाहते हैं या नहीं।

आप देख सकते हैं कि यह क्या बाईटकोड निर्देश यह रूबी एमआरआई 1.9 में उत्पन्न करता है को देखकर कुछ भी अप्रत्याशित नहीं करता है:

RubyVM::InstructionSequence::compile("c = begin; a = 5; 6; end").to_a 

[:trace, 1], 
[:trace, 1], 
[:putobject, 5], 
[:setlocal, 2], 
[:trace, 1], 
[:putobject, 6], 
[:dup], 
[:setlocal, 3], 
[:leave] 

ट्रेस स्टैक ट्रेस के लिए बस है, तो आप उस अनदेखा कर सकते हैं। डुबकी स्टैक पर अंतिम आइटम डुप्लिकेट करता है। इस उदाहरण में स्थानीय चर a की संख्या 2 है और स्थानीय चर c की संख्या 3 है (इसलिए putobject, 2 परिवर्तनीय a आदि को असाइन करेगा)। a = 5; c = 6 की तुलना में इसका एकमात्र दुष्प्रभाव dup निर्देश है, जिसका अर्थ है कि आपकी विधि का ढेर आकार 1 स्लॉट से बड़ा होगा। लेकिन यह विशेष रूप से महत्वपूर्ण नहीं है क्योंकि इसका कोई प्रभाव नहीं पड़ता है जबकि दुभाषिया इस विशेष विधि के अंदर है, और स्टैक के लिए स्मृति वैसे भी पूर्व-आरक्षित है, इसलिए इसका मतलब है कि स्टैक पॉइंटर को अन्यथा की तुलना में 1 से भी कम किया जाएगा। तो मूल रूप से कोई बदलाव नहीं है। अनुकूलन के साथ भी dup चालू हो गया है शायद गायब हो जाएगा।

+1

यह मेरे प्रश्न का उत्तर नहीं देता है। – pje

+0

जैसा मैंने कहा, यह पूरी तरह से मान्य है, इसलिए कोई अनपेक्षित परिणाम नहीं हैं। यह सिर्फ एक कोड-शैली की बात है। – mrbrdo

+0

और यह एक अच्छी राय है, लेकिन आपके जवाब में "कोई अनपेक्षित परिणाम नहीं हैं"। – pje

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