Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

Ruby 스택 추적 읽기 및 이해

애플리케이션에서 오류가 발생하면 Ruby는 예외를 발생시키고 스택 추적을 인쇄합니다. 로그에. 이 기사에서는 스택 추적을 읽는 방법과 이를 사용하여 애플리케이션에서 예외의 소스를 찾는 방법을 살펴보겠습니다.

호출 스택

메소드를 호출할 때마다 Ruby는 스택 프레임을 배치합니다. 호출 스택에서 (또는 "런타임 스택"이지만 종종 그냥 "스택"이라고 함). 스택 프레임은 메서드의 인수, 내부 변수를 위한 일부 공간 및 호출자의 반환 주소를 보유하는 메모리 할당입니다.

# divide.rb
def divide(a, b)
  "Dividing #{a} by #{b} gives #{a / b}."
end
 
puts divide(8, 4)

한 가지 방법(divide ) 다른 메서드(Fixnum#/)를 호출합니다. , 또는 / 간단히 말해서) 후자는 첫 번째 것이 완료되기 전에 실행되어야 하기 때문에 스택의 맨 위에 놓입니다. divide(8, 4)를 호출할 때 이 예에서 Ruby는 다음 작업을 순서대로 실행합니다.

  1. 8./(4) 호출
  2. 디비전의 결과 수집(2 ), 문자열에 넣습니다.
  3. 문자열 수집("Dividing 8 by 4 gives 2" ), puts를 사용하여 콘솔에 인쇄합니다.

스택 추적

스택 추적 (일반적으로 Ruby에서는 "backtrace"라고 하지만 "stack backtrace" 및 "stack traceback"이라고도 함) 프로그램을 실행하는 동안 특정 순간에 스택을 사람이 읽을 수 있는 표현입니다. / 호출에 대한 스택 추적 메소드는 다음과 같을 것이며 divide에서 호출되었음을 보여줍니다. <main>에서 호출된 2행의 메소드 5행의 방법.

divide.rb:2:in `/'
divide.rb:2:in `divide'
divide.rb:5:in `<main>'

위의 예에서 divide 인수 중 하나가 0인 메서드는 ZeroDivisionError가 됩니다. 예외입니다.

# divide_by_zero.rb
def divide(a, b)
  "Dividing #{a} by #{b} gives #{a / b}."
end
 
puts divide(8, 0)

그런 일이 발생하면 Ruby는 스택 추적과 함께 예외를 콘솔에 인쇄합니다. 스택 추적은 코드에서 각 메서드의 위치와 함께 사람이 읽을 수 있는 형식으로 스택을 표시하여 예외가 발생한 위치를 정확히 찾아내는 데 도움이 됩니다.

$ ruby divide_by_zero.rb
divide_by_zero.rb:2:in `/': divided by 0 (ZeroDivisionError)
        from divide_by_zero.rb:2:in `divide'
        from divide_by_zero.rb:5:in `<main>'
  1. 위 스택 추적의 첫 번째 줄에서 ZeroDivisionError 메시지로 "0으로 나누기"로 제기되었습니다. 예외 자체 외에도 divide_by_zero.rb:2:in `/'에서 발생했음을 알 수 있습니다. , 이는 /라는 메서드에서 예제 파일의 두 번째 줄에서 오류가 발생했음을 의미합니다. (Fixnum#/입니다. , 첫 번째 인수가 Fixnum 8이기 때문에 ).

  2. 스택 추적의 두 번째 줄은 /의 위치를 ​​보여줍니다. 에서 메서드를 호출했습니다. 이 경우 divide에서 가져온 것입니다. 2행의 방법.

  3. 마지막 줄은 divide를 보여줍니다. <main>에서 호출되었습니다. , Ruby 애플리케이션의 초기 컨텍스트를 나타냅니다. 일반적으로 "실제" 메서드 외부에서 호출되었음을 의미합니다.

참고 :Ruby 2.5에서 로거는 스택 추적을 터미널 창에 맞게 역으로 인쇄합니다. 마지막 줄은 예외가 발생한 줄 앞에 오는 예외를 보여줍니다. 위의 라인은 스택의 상위 경로입니다.

스택 추적 이해

스택 추적은 예외가 발생할 때마다 호출 스택의 현재 상태에 대한 덤프를 제공하고 문제가 발생한 위치를 찾는 데 도움이 됩니다.

스택 추적의 첫 번째 줄은 예외가 발생한 줄을 표시하지만 항상 오류의 원인을 표시하지는 않습니다. 위의 예에서 프로그램은 제대로 실행되었지만 divide에 전달된 데이터를 처리할 수 없었습니다. 방법. 스택 추적을 따라 올라가면 호출되는 위치로 연결됩니다. 문제의 원인.

언제나처럼 이 기사가 마음에 들었는지, 기사에 대해 질문이 있거나 다음에 읽고 싶은 내용이 있다면 @AppSignal로 알려주시기 바랍니다.