Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

วิธีการสอดแนมวิธีการทับทิมของคุณ

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

อย่าลืมแชร์โพสต์นี้ เพื่อให้คนได้สนุกกันมากขึ้น 🙂