যখন আপনার অ্যাপ্লিকেশনে একটি এরর হয়, রুবি একটি এক্সেপশন রেইজ করে এবং স্ট্যাক ট্রেস লগে প্রিন্ট করে। এই আর্টিকেলে, আমরা দেখব কীভাবে স্ট্যাক ট্রেস পড়া যায় এবং কীভাবে এটা ব্যবহার করে আপনার অ্যাপ্লিকেশনে একটি এক্সেপশনের উৎস সনাক্ত করতে হয়।
কল স্ট্যাক
যখনই আপনি একটি মেথড কল করেন, রুবি একটি স্ট্যাক ফ্রেম কল স্ট্যাক-এ (বা "রানটাইম স্ট্যাক", কিন্তু প্রায়শই শুধু "স্ট্যাক" বলা হয়) রাখে। স্ট্যাক ফ্রেম হলো একটি মেমরি এলোকেশন যা মেথডের আর্গুমেন্ট, ইন্টারন্যাল ভেরিয়েবলের জন্য কিছু স্পেস, এবং কলারের রিটার্ন অ্যাড্রেস ধারণ করে।
# 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 মেথডে লাইন ২-এ কল হয়েছে, যেটি মেথডে লাইন ৫-এ কল হয়েছিল।
divide.rb:2:in `/'
divide.rb:2:in `divide'
divide.rb:5:in `'
উপরের উদাহরণে, আমাদের divide মেথডকে ০ দিয়ে আর্গুমেন্ট হিসেবে কল করলে একটা 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 `'
স্ট্যাক ট্রেসের প্রথম লাইনে, আমরা দেখতে পাই একটি
ZeroDivisionErrorরেইজ হয়েছে "divided by 0" মেসেজসহ। এক্সেপশনটির পাশাপাশি, আমরা দেখতে পাই সেটি হয়েছেdivide_by_zero.rb:2:in `/'-এ, যেটি মানে আমাদের উদাহরণ ফাইলের দ্বিতীয় লাইন থেকে, একটি মেথড নামক/থেকে (যেটিFixnum#/, কারণ প্রথম আর্গুমেন্ট হলো ফিক্সনাম8)।স্ট্যাক ট্রেসের দ্বিতীয় লাইন দেখাচ্ছে
/মেথডটি কোথা থেকে কল হয়েছিল। এই কেসে, সেটি আমাদেরdivideমেথড থেকে লাইন ২-এ।লাস্ট লাইন দেখাচ্ছে
divideকল হয়েছিলথেকে, যেটি একটি রুবি অ্যাপ্লিকেশনের ইনিশিয়াল কনটেক্সটকে রেফার করে। সাধারণত, এটা মানে সেটি কল হয়েছিল যেকোনো "রিয়াল" মেথডের বাইরে থেকে।
নোট: রুবি ২.৫-এ, লগার স্ট্যাক ট্রেস রিভার্স অর্ডারে প্রিন্ট করে টার্মিনাল উইন্ডোতে ফিট করার জন্য। লাস্ট লাইন এক্সেপশন দেখাচ্ছে, তার পূর্বে এক্সেপশন হয়েছিল সেটি লাইন। তার উপরের লাইনগুলো স্ট্যাকের উপরে যাওয়ার রুট।
স্ট্যাক ট্রেস বুঝা
স্ট্যাক ট্রেস আপনাকে আপনার কল স্ট্যাকের বর্তমান স্টেটের একটি ডাম্প দেয় যখনই একটি এক্সেপশন রেইজ হয়, এবং কোথায় ভুল হয়েছে সেটা বের করতে সাহায্য করে।
যদিও স্ট্যাক ট্রেসের প্রথম লাইন এক্সেপশন ঘটেছিল সেটি লাইন দেখায়, এটা সবসময় এররের উৎস দেখায় না। উপরের উদাহরণে, প্রোগ্রাম প্রপারলি এক্সিকিউট হয়েছিল, কিন্তু divide মেথডে পাস করা ডেটা হ্যান্ডেল করতে পারলো না। স্ট্যাক ট্রেস উপরে যাওয়া দিয়ে সেটি কল হয়েছিল কোথায় সেটা পাওয়া যায়, যেটি হচ্ছে সমস্যায়ের উৎস।
সদায়, আমরা জানতে চাই আপনি এই আর্টিকেল কেমন লাগলো, আপনার কোনো প্রশ্ন আছে কিনা, এবং আপনি কী নিয়ে পড়তে চান, তাই @AppSignal-এ আমাদের জানাতে ভুলবেন না।