Computer >> Máy Tính >  >> Lập trình >> Ruby

Làm thế nào để theo dõi các phương pháp Ruby của bạn

Ruby có một hệ thống theo dõi tích hợp mà bạn có thể truy cập bằng cách sử dụng TracePoint lớp. Một số thứ bạn có thể theo dõi là lời gọi phương thức, chuỗi mới và ngoại lệ.

Tại sao bạn muốn sử dụng cái này?

Chà, nó có thể hữu ích nếu bạn muốn theo dõi việc thực thi một phương thức nào đó. Bạn sẽ có thể thấy những phương thức khác đang được gọi và giá trị trả về là gì.

Hãy xem một vài ví dụ!

Cuộc gọi phương pháp theo dõi

Hầu hết thời gian bạn sẽ muốn TracePoint để theo dõi mã ứng dụng và không phải các phương thức tích hợp sẵn (như đặt, kích thước, v.v.).

Bạn có thể thực hiện việc này bằng cách sử dụng call sự kiện.

Ví dụ :

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 }

Thao tác này in ra đường dẫn tệp, số dòng, tên sự kiện và tên phương thức.

["test.rb", 1, :call, :the_method]
["test.rb", 2, :call, :other_method]

Nếu bạn không chỉ định bất kỳ sự kiện nào, Ruby sẽ gọi khối của bạn cho tất cả chúng, dẫn đến kết quả đầu ra nhiều hơn. Vì vậy, tôi khuyên bạn nên tập trung vào các sự kiện cụ thể để tìm thấy những gì bạn muốn nhanh hơn 🙂

Đây là bảng của TracePoint sự kiện:

Tên sự kiện Mô tả
gọi Phương pháp ứng dụng
c_call Phương thức cấp C (như đặt)
quay lại Phương thức trả về (để theo dõi giá trị trả về và độ sâu lệnh gọi)
b_call Chặn cuộc gọi
b_return Chặn trả lại
tăng Nâng cao ngoại lệ
thread_begin Chủ đề mới
thread_end Kết thúc chuỗi

TracePoint + Graphviz

Nhiều phương thức sẽ thực hiện nhiều hơn chỉ 3 cuộc gọi phương thức, đặc biệt là trong mã khung, vì vậy kết quả đầu ra từ Tracepoint có thể khó hình dung.

Vì vậy, tôi đã tạo một viên đá quý cho phép bạn tạo một biểu đồ cuộc gọi trực quan như sau:

require 'visual_call_graph'

VisualCallGraph.trace { "Your method call here..." }

Điều này tạo ra một call_graph.png gửi kết quả.

Làm thế nào để theo dõi các phương pháp Ruby của bạn

Hãy nhớ rằng đây không phải là phân tích tĩnh, đây thực sự sẽ gọi phương thức!

Hiển thị Đường dẫn Tệp

Bạn có muốn biết các phương pháp này được định nghĩa ở đâu không?

Đừng lo, tôi đã giúp bạn! Tôi đã thêm một tùy chọn mà bạn có thể bật để hiển thị đường dẫn tệp cho mỗi lệnh gọi phương thức.

VisualCallGraph.trace(show_path: true) { Foo.aaa }

Kết quả nào dẫn đến :

Làm thế nào để theo dõi các phương pháp Ruby của bạn

Nếu bạn muốn xem một số đồ thị cuộc gọi lớn, bạn chỉ cần theo dõi một số phương thức Rails 😉

Giá trị trả lại

Trong phần giới thiệu, tôi đã đề cập rằng bạn cũng có thể nhận các giá trị trả về…

Đối với điều này, bạn sẽ cần theo dõi return sự kiện và sử dụng return_value phương pháp.

Ví dụ :

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

Điều này sẽ in:

Return value for the_method is AAAAAAAAAA.

Sự kiện đầu tiên

Có người đã hỏi trên reddit làm cách nào để tránh in từ “bar” khi gọi foo trong đoạn mã sau:

class Thing
  def foo
    puts "foo"
    bar
  end

  def bar
    puts "bar"
  end
end

# your code here

t = Thing.new
t.foo

Có nhiều cách để đạt được điều này, chẳng hạn như thêm một mô-đun, chuyển hướng $stdout hoặc xác định lại bar phương pháp.

Nếu bạn cảm thấy sáng tạo, hãy bình luận về bài đăng này với ý tưởng của riêng bạn!

Nhưng tôi thấy một trong những câu trả lời đặc biệt thú vị vì nó sử dụng TracePoint lớp học.

Đây rồi :

TracePoint.trace(:call) { |tp| exit if tp.method_id == :bar }

Mã này sẽ gọi exit khi phương thức bar được gọi, điều này ngăn không cho chuỗi được in khi kết thúc chương trình.

Có thể không phải là thứ bạn muốn sử dụng trong mã thực, nhưng nó chứng minh một điều về TracePoint :Các sự kiện được kích hoạt trước khi chúng xảy ra.

Một điều cần lưu ý nếu bạn định xây dựng một số loại công cụ xung quanh vấn đề này 🙂

Tóm tắt

Trong bài đăng này, bạn đã học về TracePoint lớp, cho phép bạn theo dõi một vài sự kiện như các cuộc gọi phương thức hoặc các luồng mới. Điều này có thể hữu ích như một công cụ gỡ lỗi hoặc để khám phá mã.

Hãy nhớ chia sẻ bài đăng này để nhiều người có thể thưởng thức nó 🙂