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 레벨 메소드(예:puts) |
반환 | 메서드 반환(반환 값 및 호출 깊이 추적용) |
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에서 foo
를 호출할 때 "bar"라는 단어가 인쇄되지 않도록 하는 방법을 물었습니다. 다음 코드의 메서드:
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
에 대해 배웠습니다. 메서드 호출이나 새 스레드와 같은 몇 가지 이벤트를 추적할 수 있는 클래스입니다. 이것은 디버깅 도구나 코드 탐색에 유용할 수 있습니다.
이 게시물을 공유하는 것을 잊지 마세요. 더 많은 사람들이 즐길 수 있도록 🙂