जब आपके आवेदन में कोई त्रुटि होती है, रूबी एक अपवाद उठाता है और स्टैक ट्रेस . को प्रिंट करता है लॉग को। इस लेख में, हम इस पर एक नज़र डालेंगे कि स्टैक ट्रेस को कैसे पढ़ा जाए और आपके एप्लिकेशन में अपवाद के स्रोत का पता लगाने के लिए इसका उपयोग कैसे किया जाए।
कॉल स्टैक
जब भी आप किसी विधि को कॉल करते हैं, रूबी एक स्टैक फ्रेम places रखती है कॉल स्टैक . पर (या "रनटाइम स्टैक", लेकिन अक्सर इसे "स्टैक" कहा जाता है)। स्टैक फ्रेम एक स्मृति आवंटन है जिसमें विधि के तर्क, आंतरिक चर के लिए कुछ स्थान और कॉलर का वापसी पता होता है।
# divide.rb
def divide(a, b)
"Dividing #{a} by #{b} gives #{a / b}."
end
puts divide(8, 4)
जब एक विधि (divide
) दूसरी विधि को कॉल करता है (Fixnum#/
, या /
संक्षेप में), बाद वाले को स्टैक के ऊपर रखा जाता है, क्योंकि इसे पहले समाप्त होने से पहले निष्पादित करने की आवश्यकता होती है। कॉल करते समय divide(8, 4)
इस उदाहरण में, रूबी निम्नलिखित क्रियाओं को क्रम में निष्पादित करेगी:
- कॉल करें
8./(4)
- डिवीजन का परिणाम एकत्र करें (
2
), और इसे एक स्ट्रिंग में रखें - स्ट्रिंग लीजिए (
"Dividing 8 by 4 gives 2"
), और इसेputs
. के साथ कंसोल पर प्रिंट करें
स्टैक ट्रेस
स्टैक ट्रेस (आमतौर पर रूबी में "बैकट्रेस" नाम दिया जाता है, लेकिन इसे "स्टैक बैकट्रेस" और "स्टैक ट्रेसबैक" भी कहा जाता है) आपके प्रोग्राम को चलाते समय एक विशिष्ट क्षण में स्टैक का मानव-पठनीय प्रतिनिधित्व है। /
. पर कॉल के लिए स्टैक ट्रेस विधि इस तरह दिखेगी, यह दिखाते हुए कि इसे divide
. में बुलाया गया था लाइन 2 पर विधि, जिसे <main>
. में बुलाया गया था लाइन 5 पर विधि।
divide.rb:2:in `/'
divide.rb:2:in `divide'
divide.rb:5:in `<main>'
ऊपर के उदाहरण में, हमारे divide
. को कॉल करना 0 के साथ विधि इसके तर्कों में से एक के रूप में परिणाम देगा ZeroDivisionError
अपवाद।
# divide_by_zero.rb
def divide(a, b)
"Dividing #{a} by #{b} gives #{a / b}."
end
puts divide(8, 0)
जब ऐसा होता है, रूबी कंसोल पर स्टैक ट्रेस के साथ अपवाद को प्रिंट करेगी। स्टैक ट्रेस मानव-पठनीय प्रारूप में स्टैक को आपके कोड में प्रत्येक विधि के स्थान के साथ दिखाता है, ताकि आपको यह पता लगाने में मदद मिल सके कि अपवाद कहां से आया है।
$ ruby divide_by_zero.rb
divide_by_zero.rb:2:in `/': divided by 0 (ZeroDivisionError)
from divide_by_zero.rb:2:in `divide'
from divide_by_zero.rb:5:in `<main>'
-
ऊपर स्टैक ट्रेस में पहली पंक्ति पर, हम देख सकते हैं कि एक
ZeroDivisionError
इसके संदेश के रूप में "0 से विभाजित" के साथ उठाया गया था। अपवाद के अलावा, हम देख सकते हैं कि यहdivide_by_zero.rb:2:in `/'
पर हुआ था , जिसका अर्थ है कि त्रुटि हमारी उदाहरण फ़ाइल की दूसरी पंक्ति से,/
नामक विधि से उठाई गई थी (जो हैFixnum#/
, क्योंकि पहला तर्क फिक्सनम8
. है )। -
स्टैक ट्रेस की दूसरी पंक्ति से पता चलता है कि
/
विधि से बुलाया गया था। इस मामले में, यह हमारेdivide
. से है लाइन 2 पर विधि। -
अंतिम पंक्ति दर्शाती है कि
divide
<main>
. से कॉल किया गया था , जो रूबी एप्लिकेशन के प्रारंभिक संदर्भ को संदर्भित करता है। आम तौर पर, इसका मतलब है कि इसे किसी भी "वास्तविक" विधि के बाहर से बुलाया गया था।
नोट :रूबी 2.5 में, लॉगर स्टैक ट्रेस को एक टर्मिनल विंडो में फिट करने के लिए रिवर्स में प्रिंट करता है। अंतिम पंक्ति अपवाद दिखाती है, जिस पंक्ति पर अपवाद हुआ था उससे पहले। उसके ऊपर की पंक्तियाँ स्टैक का मार्ग हैं।
स्टैक ट्रेस को समझना
जब भी कोई अपवाद उठाया जाता है, तो स्टैक ट्रेस आपको आपके कॉल स्टैक की वर्तमान स्थिति का एक डंप देता है, और यह पता लगाने में सहायक होता है कि चीजें कहां गलत हुईं।
हालांकि स्टैकट्रेस की पहली पंक्ति उस रेखा को दिखाती है जिस पर अपवाद हुआ है, यह हमेशा त्रुटि का स्रोत नहीं दिखाता है। ऊपर के उदाहरण में, प्रोग्राम ठीक से निष्पादित हुआ, लेकिन यह divide
में पास किए गए डेटा को हैंडल नहीं कर सका तरीका। स्टैक ट्रेस को ऊपर ले जाकर उस स्थान पर ले जाया जाता है जहां इसे कहा जाता है, जो है समस्या का स्रोत।
हमेशा की तरह, हमें यह जानना अच्छा लगेगा कि आपको यह लेख कैसा लगा, यदि इसके बारे में आपके कोई प्रश्न हैं, और आप आगे क्या पढ़ना चाहते हैं, तो हमें @AppSignal पर बताना सुनिश्चित करें।