IRB에서 Ruby 코드 분석: Ripper에서 Prism으로의 전환

[JA] Analyzing Ruby Code in IRB / tomoya ishida @tompng

작성자
RubyKaigi
발행일
2025년 05월 27일

핵심 요약

  • 1 IRB는 구문 강조, 자동 들여쓰기, 코드 완성 등 다양한 Ruby 코드 분석 기능을 제공하며, 기존 Ripper::Lexer 기반의 한계를 Prism으로 전환하여 개선하고 있습니다.
  • 2 구문 분석의 정확도와 유지보수성 향상을 위해 Ripper의 토큰 기반 분석에서 Prism의 AST(추상 구문 트리) 기반 분석으로 전환하는 하이브리드 접근 방식이 도입되고 있습니다.
  • 3 코드 종료 판정 및 자동 완성 기능은 Prism의 API를 활용하여 기존의 복잡하고 부정확했던 방식들을 표준화하고, 런타임 정보를 더욱 효과적으로 활용하여 정확도를 높일 계획입니다.

도입

IRB(Interactive Ruby)는 Ruby 개발 환경에서 필수적인 도구로, 사용자가 입력하는 Ruby 코드에 대해 다양한 분석을 수행합니다. 구문 강조, 자동 들여쓰기, 프롬프트 변경, 코드 완성, 코드 실행 가능 여부 판단, 실행 결과 출력 제어 등이 그 예입니다. 기존 IRB는 주로 Ripper::Lexer를 활용하여 이러한 분석을 수행했으나, 불완전한 코드 처리 및 IRB 내부에 자체적인 파서 로직이 중복되는 문제점과 유지보수성 이슈가 있었습니다. 본 발표는 이러한 한계를 극복하고 더 나은 분석 기능을 제공하기 위해 Ripper 기반의 분석을 Prism으로 전환하는 과정과 그에 따른 변화를 상세히 다룹니다.

IRB 코드 분석의 기존 방식과 한계

  • Ripper::Lexer 활용: IRB는 Ripper::Lexer를 사용하여 토큰화하고, 이를 기반으로 구문 강조 및 기본적인 중첩 상태를 파악했습니다.
  • IRB 자체 파서의 중복: Ripper가 토큰화를 위해 내부적으로 파싱을 수행함에도 불구하고, IRB는 다시 이 토큰 스트림을 자체 파서로 재분석하는 비효율적인 구조를 가지고 있었습니다. 이는 유지보수성을 저해하는 요인이었습니다.
  • 불완전한 코드 처리: Ripper::Lexer는 불완전한 코드도 토큰화할 수 있었지만, 복잡한 Ruby 구문(예: 연산자 우선순위, Endless Method, Modifier If)을 IRB의 자체 “서브셋 언어” 파서로 정확히 처리하는 데 한계가 있었습니다. 특히, 연산자 우선순위를 무시한 중첩 분석은 잘못된 자동 들여쓰기 결과를 초래하기도 했습니다.

Prism으로의 전환: 개선 방향

  • Prism 도입 배경: Ruby 3.2부터 AbstractSyntaxTree에 오류 허용 옵션이 추가되고, Prism이 번들드 젬으로 제공되면서 오류 허용 파싱이 가능해졌습니다. 이는 불완전한 IRB 입력 코드 분석에 적합한 환경을 제공합니다.
  • 하이브리드 구문 강조: Ripper 토큰 기반의 단순한 색상 지정 방식은 :”#{var}”와 같은 복잡한 심볼이나 문자열 삽입 구문에서 정확한 색상 적용이 어려웠습니다. Prism의 AST를 활용하여 InterpolatedSymbolNode와 같은 노드를 식별, 토큰 기반 색상 지정 규칙을 오버라이드하는 하이브리드 방식을 통해 정확도를 높입니다. Prism.parse_lex 메서드는 토큰과 AST를 동시에 제공하여 이러한 접근을 용이하게 합니다.
  • AST 기반 중첩 분석: 기존의 단순한 괄호/def/end 기반 중첩 분석 대신, Prism의 AST를 트래버스하여 BlockNode, CallNode, StringNode 등 실제 구문 요소의 시작과 끝 위치를 기반으로 중첩 상태를 계산합니다. 이는 Ruby의 복잡한 구문 규칙을 정확하게 반영하여 자동 들여쓰기 및 프롬프트 변경의 정확도를 향상시킵니다.
  • 코드 종료 판정 표준화: 기존에는 CRuby, JRuby, eval 등 여러 방법으로 코드 종료 여부를 판단했으며, eval을 활용한 트릭은 매직 코멘트 무효화와 같은 부작용을 일으켰습니다. Prism.parse(…).success? 및 errors API를 사용하여 코드 종료 판정을 단일화하고, 1행에 불필요한 코드를 삽입하는 문제를 해결합니다.
  • 자동 완성 기능 강화: Prism의 AST와 scopes API를 활용하여 커서 위치의 노드를 정확히 파악하고, replete_type_completer 젬과 연동하여 더욱 정교한 타입 기반 자동 완성을 제공합니다. 특히, 런타임 값을 활용한 타입 파라미터 지연 전개 방식을 통해 Array와 같은 컬렉션의 중첩된 요소에 대한 타입 정보를 유지하며 정확한 완성을 지원합니다.

결론

IRB는 Ripper에서 Prism으로의 전환을 통해 Ruby 코드 분석의 정확도와 유지보수성을 크게 향상시키고 있습니다. 특히, Prism의 AST를 활용한 하이브리드 구문 강조, 정확한 중첩 분석, 그리고 표준화된 코드 종료 판정 및 강화된 자동 완성 기능은 사용자 경험을 한층 더 개선할 것입니다. 이 전환은 IRB뿐만 아니라 Rog와 같은 다른 Ruby 라이브러리에서도 진행되고 있으며, Ruby 생태계 전반의 개발 도구들이 더 견고하고 지능적으로 발전하는 중요한 단계가 될 것입니다. 비록 아직 진행 중인 부분이 있지만, Prism 기반의 분석은 IRB를 더욱 강력하고 효율적인 도구로 만들 것으로 기대합니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!