2010-01-24 14 views
28

क्यों कि निम्नलिखित कोड ठीकरूबी प्रिंट इंजेक्षन Do सिंटेक्स

p (1..1000).inject(0) { |sum, i| 
    sum + i 
} 

लेकिन, निम्नलिखित कोड एक त्रुटि

p (1..1000).inject(0) do |sum, i| 
    sum + i 
end 

warning: do not use Fixnums as Symbols 
in `inject': 0 is not a symbol (ArgumentError) 

वे बराबर नहीं होना चाहिए देता है चलाता है यह क्या है?

उत्तर

34

घुंघराले ब्रेसिज़ का उपयोग करके लिखा गया ब्लॉक इंजेक्ट विधि से बांधता है, जो आपका इरादा है, और यह ठीक काम करेगा।

हालांकि, ब्लॉक/डू ब्लॉक में encapsulated ब्लॉक, पी-विधि से बंधेगा। इस वजह से, इंजेक्शन कॉल में एक संबंधित ब्लॉक नहीं है। इस मामले में, इंजेक्ट तर्क की व्याख्या करेगा, इस मामले में 0, प्रत्येक ऑब्जेक्ट पर कॉल करने के लिए एक विधि नाम के रूप में। बाकूस 0 एक प्रतीक नहीं है जिसे एक विधि कॉल में परिवर्तित किया जा सकता है, इससे एक चेतावनी मिल जाएगी।

6

ऐसा करने/अंत और कोष्ठक के बीच बंधन में अंतर का एक प्रभाव दिखाई देता है:

कोष्ठक, इस्तेमाल किया के रूप में आप से ऊपर हैं, पिछले समारोह श्रृंखलित जबकि/अंत पहले करने के लिए बाध्य होगा करने के लिए बाध्य होगा।

मुझे लगता है कि यह कहने का एक अजीब तरीका है, लेकिन मूल रूप से पहला उदाहरण ब्लॉक को इंजेक्ट करने के लिए ब्लॉक पास कर रहा है, जबकि दूसरा वास्तव में ब्लॉक को पहली विधि 'पी' में पारित करने का प्रयास कर रहा है।

+1

"जबकि दूसरा वास्तव में पहली विधि के लिए ब्लॉक पारित करने के लिए कोशिश कर रहा है (1 ..1000)। " इसे "पहली विधि 'पी' में बनाएं" और आप सही हैं। – sepp2k

+0

मैंने इसे सही किया। अनदेखी कि उपरोक्त कोड में पहली नज़र में! – Pete

6

समस्या शुरुआत में p के साथ है। आप इन को छोड़ देते हैं, तो आपको लगता है कि दोनों ठीक से काम देखेंगे:

# Works! 
[5, 6, 7].inject(0) do |sum, i| # Correctly binds to `inject`. 
    sum + i 
end 

# Works too! 
[5, 6, 7].inject(0) { |sum, i| # Correctly binds to `inject`. 
    sum + i 
} 

लेकिन यह काम नहीं करेगा:

# Kablammo! "p" came first, so it gets first dibs on your do..end block. 
# Now inject has no block to bind to! 
p [5, 6, 7].inject(0) do |sum, i| # Binds to `p` -- not what you wanted. 
    sum + i 
end 
संबंधित मुद्दे