Ruby-এ একটি বিল্ট-ইন ট্রেসিং সিস্টেম রয়েছে, যেটি আপনি TracePoint ক্লাস ব্যবহার করে অ্যাক্সেস করতে পারেন। এর মাধ্যমে মেথড কল, নতুন থ্রেড এবং এক্সেপশন সহ বিভিন্ন ইভেন্ট ট্রেস করা যায়।
আপনি কেন এটি ব্যবহার করবেন?
যদি আপনি কোনো নির্দিষ্ট মেথডের এক্সিকিউশন ট্রেস করতে চান, তবে এটি খুবই উপকারী। এর মাধ্যমে আপনি দেখতে পাবেন কী মেথডগুলো কল হচ্ছে এবং তাদের রিটার্ন ভ্যালু কী।
চলুন কিছু উদাহরণ দেখি!
মেথড কল ট্রেস করা
বেশির ভাগ সময় আপনি TracePoint-কে অ্যাপ্লিকেশন কোড ট্রেস করার জন্য ব্যবহার করবেন, বিল্ট-ইন মেথডগুলো (যেমন puts, size ইত্যাদি) ট্রেস করার জন্য নয়।
আপনি এটি call ইভেন্ট ব্যবহার করে করতে পারেন।
উদাহরণ:
def the_method; other_method; end
def other_method; end
def start_trace
trace = TracePoint.new(:call) { |tp| p [tp.path, tp.lineno, tp.event, tp.method_id] }
trace.enable
yield
trace.disable
end
start_trace { the_method }
এটি ফাইল পাথ, লাইন নম্বর, ইভেন্টের নাম এবং মেথডের নাম প্রিন্ট করবে।
["test.rb", 1, :call, :the_method] ["test.rb", 2, :call, :other_method]
যদি আপনি কোনো ইভেন্ট নির্দিষ্ট না করেন, তবে Ruby আপনার ব্লকে সব ইভেন্টের জন্য কল করবে, ফলে আউটপুট বেশি হবে। তাই আমি সুপারিশ করব নির্দিষ্ট ইভেন্টের ওপর ফোকাস করার জন্য, যাতে আপনি দ্রুত খুঁজে পেতে পারেন 🙂
এখানে TracePoint ইভেন্টগুলোর একটি টেবিল দেওয়া হলো:
| ইভেন্টের নাম | বিবরণ |
|---|---|
| call | অ্যাপ্লিকেশন মেথড |
| c_call | C-লেভেল মেথড (যেমন puts) |
| return | মেথড রিটার্ন (রিটার্ন ভ্যালু এবং কল ডেপথ ট্রেস করার জন্য) |
| b_call | ব্লক কল |
| b_return | ব্লক রিটার্ন |
| raise | এক্সেপশন রেইজ |
| thread_begin | নতুন থ্রেড |
| thread_end | থ্রেড শেষ |
TracePoint + Graphviz
অনেক মেথড মাত্র ৩টি মেথড কল করে না, বিশেষ করে ফ্রেমওয়ার্ক কোডে, তাই TracePoint-র আউটপুট ভিজ্যুয়ালাইজ করা কঠিন হতে পারে।
সেজন্য আমি একটি জেম বানিয়েছি যা আপনাকে একটি ভিজ্যুয়াল কল গ্রাফ তৈরি করতে দেবে:
require 'visual_call_graph'
VisualCallGraph.trace { "আপনার মেথড কল এখানে..." }
এটি ফলাফলসহ একটি call_graph.png ফাইল জেনারেট করবে।

মনে রাখবেন যে এটি স্ট্যাটিক অ্যানালাইসিস নয়, এটি আসলে মেথডটি কল করবে!
ফাইল পাথ দেখানো
আপনি কি জানতে চান এই মেথডগুলো কোথায় ডিফাইন করা হয়েছে?
চিন্তা করবেন না, আমি তা কভার করেছি! আমি একটি অপশন যোগ করেছি যা আপনাকে প্রতিটি মেথড কলের ফাইল পাথ দেখাতে সক্ষম করে।
VisualCallGraph.trace(show_path: true) { Foo.aaa }
ফলাফল:

আপনি যদি বড় বড় কল গ্রাফ দেখতে চান, তবে শুধু কিছু Rails মেথড ট্রেস করলেই হবে 😉
রিটার্ন ভ্যালু
প্রস্তাবনায় আমি উল্লেখ করেছিলাম যে আপনি রিটার্ন ভ্যালুও পেতে পারেন...
এর জন্য আপনাকে return ইভেন্ট ট্রেস করতে হবে এবং return_value মেথড ব্যবহার করতে হবে।
উদাহরণ:
def the_method; "A" * 10; end
trace = TracePoint.new(:return) { |tp| puts "Return value for #{tp.method_id} is #{tp.return_value}." }
trace.enable
the_method
trace.disable
এটি প্রিন্ট করবে:
Return value for the_method is AAAAAAAAAA.
ইভেন্ট ফাস্ট (ইভেন্টগুলো আগে ঘটে)
Reddit-এ কেউ জিজ্ঞেস করেছিলেন নিচের কোডে foo মেথড কল করলে "bar" শব্দটি প্রিন্ট হওয়া থেকে কীভাবে বাঁচানো যায়:
class Thing
def foo
puts "foo"
bar
end
def bar
puts "bar"
end
end
# আপনার কোড এখানে
t = Thing.new
t.foo
এই সমস্যা সমাধানের অনেক উপায় আছে, যেমন মডিউল প্রিপেন্ড করা, $stdout রিডাইরেক্ট করা বা bar মেথড রিডিফাইন করা।
আপনি যদি সৃজনশীল হন, তবে এই পোস্টে আপনার নিজের আইডিয়া কমেন্ট করুন!
কিন্তু আমি একটি উত্তর খুবই আকর্ষণীয় পেলাম কারণ সেটি TracePoint ক্লাস ব্যবহার করেছিল।
সেটি এখানে:
TracePoint.trace(:call) { |tp| exit if tp.method_id == :bar }
এই কোডটি bar মেথড কল হলে exit কল করবে, যা প্রোগ্রামটি শেষ করে দিয়ে স্ট্রিংটি প্রিন্ট হওয়া থেকে বাঁচাবে।
বাস্তব কোডে এটি ব্যবহার করা ভালো অভ্যাস নয়, কিন্তু এটি TracePoint-র একটি বিষয় প্রমাণ করে: ইভেন্টগুলো ঘটার আগেই ট্রিগার হয়।
যদি আপনি এর চারপাশে কোনো টুল বানাতে চান, তবে এই বিষয়টি মনে রাখবেন 🙂
সারসংক্ষেপ
এই পোস্টে আপনি TracePoint ক্লাস সম্পর্কে শিখেছেন, যা আপনাকে মেথড কল বা নতুন থ্রেডের মতো কিছু ইভেন্ট ট্রেস করতে দেয়। এটি ডিবাগিং টুল বা কোড এক্সপ্লোরেশনের জন্য খুবই উপকারী হতে পারে।
এই পোস্টটি শেয়ার করতে ভুলবেন না যাতে আরো মানুষ উপকৃত হয় 🙂