Ruby มีระบบติดตามในตัว ซึ่งคุณสามารถเข้าถึงได้โดยใช้ TracePoint ระดับ. บางสิ่งที่คุณสามารถติดตามได้คือการเรียกใช้เมธอด เธรดใหม่ และข้อยกเว้น
ทำไมคุณถึงต้องการใช้สิ่งนี้?
มันอาจจะมีประโยชน์ถ้าคุณต้องการติดตามการดำเนินการของวิธีการบางอย่าง คุณจะสามารถดูว่ามีการเรียกใช้เมธอดอื่นใด &ค่าส่งคืนคืออะไร
มาดูตัวอย่างกัน!
การเรียกวิธีการติดตาม
ส่วนใหญ่คุณจะต้องการ TracePoint เพื่อติดตามโค้ดของแอปพลิเคชัน &ไม่ใช่เมธอดในตัว (เช่น วาง ขนาด ฯลฯ)
คุณสามารถทำได้โดยใช้ 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 เหตุการณ์:
| ชื่อกิจกรรม | คำอธิบาย |
|---|---|
| โทร | วิธีสมัคร |
| c_call | วิธีระดับ C (เช่นทำให้) |
| คืนสินค้า | วิธีการส่งคืน (สำหรับการติดตามค่าที่ส่งคืน &ความลึกของการโทร) |
| b_call | บล็อคการโทร |
| b_return | บล็อกการคืนสินค้า |
| เพิ่ม | ยกข้อยกเว้น |
| thread_begin | กระทู้ใหม่ |
| thread_end | การสิ้นสุดกระทู้ |
TracePoint + Graphviz
หลายวิธีจะเรียกมากกว่า 3 เมธอด โดยเฉพาะอย่างยิ่งในโค้ดเฟรมเวิร์ก ดังนั้นเอาต์พุตจาก Tracepoint มองเห็นได้ยาก
ดังนั้นฉันจึงสร้างอัญมณีที่ให้คุณสร้างกราฟการโทรแบบเห็นภาพได้ดังนี้:
require 'visual_call_graph'
VisualCallGraph.trace { "Your method call here..." }
สิ่งนี้จะสร้าง 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 ว่าเป็นไปได้อย่างไรที่จะหลีกเลี่ยงการพิมพ์คำว่า “bar” เมื่อเรียก foo วิธีในรหัสต่อไปนี้:
class Thing
def foo
puts "foo"
bar
end
def bar
puts "bar"
end
end
# your code here
t = Thing.new
t.foo
มีหลายวิธีในการดำเนินการนี้ เช่น การเพิ่มโมดูล การเปลี่ยนเส้นทาง $stdout หรือนิยามใหม่ของ bar วิธีการ
หากคุณรู้สึกสร้างสรรค์ แสดงความคิดเห็นในโพสต์นี้ด้วยแนวคิดของคุณเอง!
แต่ฉันพบคำตอบที่น่าสนใจเป็นพิเศษเพราะว่าใช้ TracePoint ชั้นเรียน
นี่เลย :
TracePoint.trace(:call) { |tp| exit if tp.method_id == :bar }
รหัสนี้จะเรียก exit เมื่อเมธอด bar ถูกเรียกซึ่งป้องกันไม่ให้พิมพ์สตริงโดยการสิ้นสุดโปรแกรม
อาจไม่ใช่สิ่งที่คุณต้องการใช้ในโค้ดจริง แต่มันพิสูจน์สิ่งหนึ่งเกี่ยวกับ TracePoint :เหตุการณ์จะถูกทริกเกอร์ก่อนที่จะเกิดขึ้น
สิ่งที่ควรทราบหากคุณจะสร้างเครื่องมือเกี่ยวกับเรื่องนี้ 🙂
สรุป
ในโพสต์นี้ คุณได้เรียนรู้เกี่ยวกับ TracePoint class ซึ่งช่วยให้คุณติดตามเหตุการณ์บางอย่าง เช่น การเรียกใช้เมธอดหรือเธรดใหม่ ซึ่งจะมีประโยชน์ในฐานะเครื่องมือดีบั๊กหรือสำหรับการสำรวจโค้ด
อย่าลืมแชร์โพสต์นี้ เพื่อให้คนได้สนุกกันมากขึ้น 🙂