जब आपके एप्लिकेशन में कोई त्रुटि होती है, तो रूबी एक अपवाद उठाता है और स्टैक ट्रेस को लॉग में प्रिंट करता है। इस लेख में, हम देखेंगे कि स्टैक ट्रेस को कैसे पढ़ें और इसका उपयोग अपने एप्लिकेशन में अपवाद के स्रोत का पता लगाने के लिए कैसे करें।
कॉल स्टैक
जब भी आप कोई मेथड कॉल करते हैं, रूबी कॉल स्टैक (या "रनटाइम स्टैक", लेकिन अक्सर सिर्फ "स्टैक" कहा जाता है) पर एक स्टैक फ्रेम रखता है। स्टैक फ्रेम एक मेमोरी आवंटन है जो मेथड के आर्गुमेंट, आंतरिक वेरिएबल के लिए कुछ स्थान, और कॉलर के रिटर्न एड्रेस को रखता है।
# 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के साथ कंसोल पर प्रिंट करें
स्टैक ट्रेस
स्टैक ट्रेस (आमतौर पर रूबी में "बैकट्रेस" नामित, लेकिन "स्टैक बैकट्रेस" और "स्टैक ट्रेसबैक" के रूप में भी संदर्भित) एक विशिष्ट क्षण पर आपके प्रोग्राम को चलाते समय स्टैक का मानव-पठनीय प्रतिनिधित्व है। / मेथड के कॉल के लिए स्टैक ट्रेस इस तरह दिखेगा, जो दर्शाता है कि इसे लाइन 2 पर divide मेथड में कॉल किया गया था, जिसे लाइन 5 पर <main> मेथड में कॉल किया गया था।
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को "divided by 0" संदेश के साथ उठाया गया था। अपवाद के अलावा, हम देख सकते हैं कि यहdivide_by_zero.rb:2:in `/'पर हुआ, जिसका अर्थ है कि त्रुटि हमारी उदाहरण फाइल की दूसरी लाइन से,/नामक मेथड से उठाई गई थी (जोFixnum#/है, क्योंकि पहला आर्गुमेंट फिक्सनम8है)।स्टैक ट्रेस की दूसरी लाइन दिखाती है कि
/मेथड को कहां से कॉल किया गया था। इस मामले में, यह हमारेdivideमेथड से लाइन 2 पर है।आखिरी लाइन दिखाती है कि
divideको<main>से कॉल किया गया था, जो रूबी एप्लिकेशन के प्रारंभिक संदर्भ को संदर्भित करता है। आम तौर पर, इसका मतलब है कि इसे किसी "असली" मेथड के बाहर से कॉल किया गया था।
नोट: रूबी 2.5 में, लॉगर स्टैक ट्रेस को रिवर्स ऑर्डर में प्रिंट करता है ताकि वे टर्मिनल विंडो में फिट हो सकें। आखिरी लाइन अपवाद दिखाती है, जिसके पहले वह लाइन होती है जिस पर अपवाद हुआ। उसके ऊपर की लाइनें स्टैक तक का रास्ता हैं।
स्टैक ट्रेस समझना
स्टैक ट्रेस आपको जब भी कोई अपवाद उठाया जाता है तो आपके कॉल स्टैक की वर्तमान स्थिति का डंप देता है, और यह पता लगाने में मददगार होता है कि चीजें कहां गलत हुईं।
हालांकि स्टैक ट्रेस की पहली लाइन उस लाइन को दिखाती है जिस पर अपवाद हुआ, यह हमेशा त्रुटि का स्रोत नहीं दिखाती। ऊपर के उदाहरण में, प्रोग्राम ठीक से निष्पादित हुआ, लेकिन यह divide मेथड को पास किए गए डेटा को संभाल नहीं सका। स्टैक ट्रेस पर ऊपर जाने से जहां इसे कॉल किया गया था, वहां पहुंचा जाता है, जो समस्या का स्रोत है।
हमेशा की तरह, हमें यह जानकर खुशी होगी कि आपको यह लेख कैसा लगा, यदि आपके कोई प्रश्न हैं, और आप आगे क्या पढ़ना चाहेंगे, तो @AppSignal पर हमें बताना सुनिश्चित करें।