런타임 코드 자동 리팩토링을 통한 Deprecation 처리 제안

[JA] On-the-fly Suggestions of Rewriting Method Deprecations / Masato Ohba @ohbarye

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

핵심 요약

  • 1 RubyDepre Gem은 런타임에 Deprecated 메서드 호출을 감지하고, 정의된 규칙에 따라 사용자 코드를 자동으로 리팩토링하거나 패치 파일을 생성하여 Deprecation 해소를 돕는 도구입니다.
  • 2 이 도구는 Pharo 언어의 DepreWriter에서 영감을 받아 동적 타입 언어의 정적 분석 한계를 극복하고, 개발자의 마이그레이션 부담을 줄이는 것을 목표로 합니다.
  • 3 현재는 테스트 및 로컬 환경 사용을 전제로 하며, 복잡한 케이스 처리, 효율성 개선, 그리고 Ruby 에코시스템 내 통합 방안 모색이 향후 과제입니다.

도입

발표는 RubyKaigi에서 Deprecation(더 이상 사용되지 않는 기능) 문제에 대한 새로운 접근 방식을 제안합니다. 프로그래밍 언어에서 Deprecation은 라이브러리/언어 개발자와 사용자 모두에게 보편적인 도전 과제이며, 기존의 문서화, 런타임 경고, 정적/동적 분석 방식만으로는 마이그레이션 비용과 개발자의 피로도가 높다는 문제점을 지적합니다. 발표자는 이러한 문제를 해결하기 위해 런타임에 Deprecated 코드를 자동으로 수정하는 도구인 'RubyDepre' Gem을 소개하고, 그 구현 배경과 원리를 설명합니다.

발표자는 Deprecation 문제 해결을 위한 RubyDepre Gem의 구현 과정과 주요 도전 과제를 상세히 설명합니다.

1. RubyDepre Gem 소개 및 영감

  • Pharo 언어의 DepreWriter: Smalltalk 기반의 객체 지향 언어인 Pharo에는 런타임에 Deprecated 코드를 자동 리팩토링하는 DepreWriter 도구가 존재합니다. 이는 Deprecated 메서드 호출 시 예외를 발생시키고, 해당 호출 지점을 변환한 후 실행을 계속하는 방식으로 동작합니다.
  • 동적 타입 언어의 한계 극복: Pharo의 접근 방식은 동적 타입 언어에서 정적 분석만으로는 정확한 수정 범위를 파악하기 어려운 문제(예: 동일한 이름의 메서드가 여러 라이브러리에 존재)를 런타임 정보를 활용하여 해결합니다. 발표자는 이 아이디어를 Ruby에 적용하고자 했습니다.

2. RubyDepre Gem 구현 상세

  • 변환 규칙 정의: deprewrite 메서드를 통해 Deprecated 메서드 이름과 from (기존 코드 패턴), to (변환될 코드 패턴) 규칙을 정의합니다.
  • Synvert Gem 활용: 내부적으로 Synvert Gem을 사용하여 AST(추상 구문 트리) 기반의 코드 변환을 수행합니다. 특히 Prism 파서를 통해 코드의 CallNode를 식별하고, node_mutation_ruby를 활용하여 변환합니다.
  • 메서드 호출 인터셉션: alias_methoddefine_method를 사용하여 Deprecated 메서드 호출을 가로챕니다. 가로챈 호출 내에서 caller 정보를 통해 호출자의 소스 파일을 읽고, Prism으로 AST를 분석하여 정확한 호출 노드를 찾습니다. from 규칙은 특정 호출 패턴만 변환하도록 정밀하게 대상을 지정하는 데 사용됩니다.
  • 코드 재구성: 변환된 코드와 원본 코드의 앞뒤 부분을 결합하여 수정된 소스 파일을 생성합니다.

3. 런타임 코드 변환의 안전성 및 출력 모드

  • 안전성 문제: 런타임에 실제 동작 중인 코드를 직접 수정하는 것은 Ruby 환경에서 안전하지 않을 수 있습니다 (예: 코드 재실행으로 인한 부작용, 상수 재정의 문제).
  • 사용 환경 및 출력 모드: 따라서 RubyDepre는 주로 테스트 및 로컬 환경에서의 사용을 권장하며, 세 가지 출력 모드를 제공합니다.
    • 로그 모드: Deprecation 해소 방법을 로그로 출력합니다.
    • Diff 모드: 수정 사항을 .diff 패치 파일로 생성하여 사용자가 수동으로 적용할 수 있도록 합니다.
    • 직접 파일 수정 모드: 위험하지만, 실제 파일을 직접 수정합니다 (데모에서 시연).

4. Ruby 에코시스템에서의 수용 가능성

  • 가장 큰 과제: RubyDepre가 언어 내장 기능이 아닌 서드파티 Gem이라는 점이 수용에 가장 큰 걸림돌입니다.
  • 이상적인 시나리오: Pharo처럼 언어에 내장된다면 라이브러리 개발자가 변환 규칙을 포함하여 배포하고, 사용자는 코드 실행만으로 Deprecation을 해소할 수 있어 매우 편리할 것입니다.
  • 차선책: 라이브러리 개발자가 사용하지 않더라도, 사용자 스스로 자신의 코드베이스 내 Deprecation을 해결하기 위한 도구로 활용할 수 있습니다. 이는 라이브러리 메서드에 몽키 패치로 deprewrite 규칙을 적용하는 방식이 될 수 있습니다.

결론

발표자는 `RubyDepre` Gem이 Deprecation 문제 해결에 대한 흥미로운 가능성을 제시하지만, 여전히 해결해야 할 과제들이 많다고 언급합니다. 특히 메타 프로그래밍이나 DSL 사용과 같은 복잡한 코드 패턴에 대한 대응, 변환 로직의 효율성 개선 (중복 변환 방지), 그리고 외부 Gem 의존성을 줄여 순수 Ruby Gem으로 만드는 것이 향후 연구 및 개발 방향입니다. 궁극적으로 발표자는 Ruby 에코시스템 전반에 걸쳐 Deprecation을 보다 쉽고 고통 없이 처리할 수 있는 메커니즘이 도입된다면, Ruby의 진화 속도를 가속화하고 개발자 경험을 크게 향상시킬 수 있을 것이라는 비전을 제시하며, 이러한 논의가 Ruby 커뮤니티에서 활발히 이루어지기를 기대합니다.

댓글 0

댓글 작성

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

아직 댓글이 없습니다

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