2010-10-26 30 views
8

करता है किसी को भी कारण है कि मैं यह लिख सकते हैं:रूबी जबकि वाक्य रचना

ruby-1.8.7-p302 > a = %w(a b c) 
=> ["a", "b", "c"] 
ruby-1.8.7-p302 > while (i = a.shift) do; puts i ; end 
a 
b 
c 
=> nil 

कौन सा है, जबकि करने के लिए एक ब्लॉक गुजर तरह दिखता है। और न:

while(i = a.shift) { puts i; } 

इसकी वजह जबकि वाक्य रचना की "do" है है बस syntaxic चीनी और कुछ भी नहीं के साथ एक ब्लॉक के "do" ऐसा करने के लिए के रूप में?

+0

महान सवाल! –

उत्तर

12

यह है क्योंकि while वाक्य रचना की do सिर्फ syntaxic चीनी है और कुछ भी नहीं के रूप में एक ब्लॉक के do से कोई लेना देना?

अधिक या कम, हाँ। यह वाक्य रचनात्मक चीनी नहीं है, यह केवल एक अंतर्निहित भाषा निर्माण है, जैसे def या class, जैसा कि @meagar पहले ही लिखा है।

इसमें ब्लॉक के do से कोई लेना देना नहीं है, सिवाय इसके कि कीवर्ड महंगे हैं और कीवर्ड का पुन: उपयोग करने से समझदारी होती है। (द्वारा "महंगा" मेरा मतलब है कि वे उसकी अभिव्यक्ति में प्रोग्रामर की सीमा।)

एक while पाश में, वहाँ हालत से ब्लॉक को अलग करने के दो तरीके हैं:

  1. do कीवर्ड और
  2. एक अभिव्यक्ति विभाजक।

, बारी में, दो अलग अलग अभिव्यक्ति रूबी में विभाजक हैं:

  1. अर्धविराम ; और
  2. एक नई पंक्ति

तो, निम्न में से सभी तीन मान्य हैं:

while i = a.shift do puts i end # do 

while i = a.shift; puts i end # semicolon 

while i = a.shift 
    puts i end     # newline 

[ओब्वी हां, कि आखिरी व्यक्ति इस तरह से लिखा नहीं जाएगा, आप से मेल खाने के लिए समर्पित एक नई लाइन पर end डाल देंगे। मैं सिर्फ यह दिखाना चाहता था कि while लूप के हिस्सों को अलग करने के लिए न्यूनतम आवश्यक क्या है।]

वैसे: यह स्थिति को कोष्ठक में रखने के लिए अत्यधिक गैर-मूर्खतापूर्ण है। आपके कोड में बहुत सारे अतिसंवेदनशील अर्धविराम भी हैं। और परिवर्तनीय नाम i आमतौर पर एक सूचकांक के लिए आरक्षित है, तत्व नहीं। (मैं सामान्य रूप से सामान्य तत्वों के लिए el का उपयोग करता हूं, लेकिन मुझे अधिक अर्थपूर्ण नाम पसंद हैं।)

यह मैन्युअल रूप से संग्रह को पुन: स्थापित करने के लिए अत्यधिक गैर-मूर्खतापूर्ण है।आपका कोड ज्यादा बेहतर रूप में

a.each(&method(:puts)).clear 

लिखा जाएगा इतना ही नहीं यह बहुत आसान समझने के लिए इस करता है (सरणी के सभी तत्वों को प्रिंट और इसे से सभी आइटम हटाना), यह भी है बहुत आसान लिखने के लिए (वहाँ है समाप्ति की स्थिति गलत होने का कोई तरीका नहीं है, या किसी असाइनमेंट को खराब कर दिया गया है)। यह भी अधिक कुशल होता है: आपका संस्करण Θ (एन) है, यह Θ (एन) है।

और वास्तव में, यह वास्तव में नहीं है कि आप इसे कैसे लिखेंगे, या तो Kernel#puts पहले से ही उस व्यवहार को लागू करता है, वैसे भी। यह बहुत ही पिछले एक 100% बराबर नहीं है: तो, क्या तुम करोगी वास्तव में लिखने इस

puts a 
a.clear 

या शायद इस

a.tap(&method(:puts)).clear 

[नोट है। यह एक खाली सरणी के लिए एक नई लाइन प्रिंट करता है, अन्य सभी कुछ प्रिंट नहीं करते हैं।]

सरल। स्पष्ट। संक्षिप्त। अर्थपूर्ण। फास्ट।

तुलना करें कि करने के लिए:

while (i = a.shift) do; puts i ; end 

मैं वास्तव में 100% स्पष्ट यह क्या करता है कि अनेक बार चलाने के लिए किया था।

+0

शानदार। मुझे बुकमार्क करना और इसका अध्ययन करना है। :) –

+1

विधि # to_proc ... मुझे लगता है कि मैं बस थोड़ा सा jorg –

+0

बहुत अच्छा प्यार में गिर गया, बहुत धन्यवाद धन्यवाद! – marcgg

6

while कोई ब्लॉक नहीं लेता है, यह एक भाषा निर्माण है। do वैकल्पिक है:

while (i = a.shift) 
    puts i 
end 
संबंधित मुद्दे