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 ซึ่งช่วยให้คุณติดตามเหตุการณ์บางอย่าง เช่น การเรียกใช้เมธอดหรือเธรดใหม่ ซึ่งจะมีประโยชน์ในฐานะเครื่องมือดีบั๊กหรือสำหรับการสำรวจโค้ด
อย่าลืมแชร์โพสต์นี้ เพื่อให้คนได้สนุกกันมากขึ้น 🙂