발표자는 Deprecation 문제 해결을 위한 RubyDepre Gem의 구현 과정과 주요 도전 과제를 상세히 설명합니다.
1. RubyDepre Gem 소개 및 영감
- Pharo 언어의 DepreWriter: Smalltalk 기반의 객체 지향 언어인 Pharo에는 런타임에 Deprecated 코드를 자동 리팩토링하는 DepreWriter도구가 존재합니다. 이는 Deprecated 메서드 호출 시 예외를 발생시키고, 해당 호출 지점을 변환한 후 실행을 계속하는 방식으로 동작합니다.
- 동적 타입 언어의 한계 극복: Pharo의 접근 방식은 동적 타입 언어에서 정적 분석만으로는 정확한 수정 범위를 파악하기 어려운 문제(예: 동일한 이름의 메서드가 여러 라이브러리에 존재)를 런타임 정보를 활용하여 해결합니다. 발표자는 이 아이디어를 Ruby에 적용하고자 했습니다.
2. RubyDepre Gem 구현 상세
- 변환 규칙 정의: deprewrite메서드를 통해 Deprecated 메서드 이름과from(기존 코드 패턴),to(변환될 코드 패턴) 규칙을 정의합니다.
- SynvertGem 활용: 내부적으로- SynvertGem을 사용하여 AST(추상 구문 트리) 기반의 코드 변환을 수행합니다. 특히- Prism파서를 통해 코드의- CallNode를 식별하고,- node_mutation_ruby를 활용하여 변환합니다.
- 메서드 호출 인터셉션: alias_method와define_method를 사용하여 Deprecated 메서드 호출을 가로챕니다. 가로챈 호출 내에서caller정보를 통해 호출자의 소스 파일을 읽고,Prism으로 AST를 분석하여 정확한 호출 노드를 찾습니다.from규칙은 특정 호출 패턴만 변환하도록 정밀하게 대상을 지정하는 데 사용됩니다.
- 코드 재구성: 변환된 코드와 원본 코드의 앞뒤 부분을 결합하여 수정된 소스 파일을 생성합니다.
3. 런타임 코드 변환의 안전성 및 출력 모드
- 안전성 문제: 런타임에 실제 동작 중인 코드를 직접 수정하는 것은 Ruby 환경에서 안전하지 않을 수 있습니다 (예: 코드 재실행으로 인한 부작용, 상수 재정의 문제).
- 사용 환경 및 출력 모드: 따라서 RubyDepre는 주로 테스트 및 로컬 환경에서의 사용을 권장하며, 세 가지 출력 모드를 제공합니다.- 로그 모드: Deprecation 해소 방법을 로그로 출력합니다.
- Diff 모드: 수정 사항을 .diff패치 파일로 생성하여 사용자가 수동으로 적용할 수 있도록 합니다.
- 직접 파일 수정 모드: 위험하지만, 실제 파일을 직접 수정합니다 (데모에서 시연).
 
4. Ruby 에코시스템에서의 수용 가능성
- 가장 큰 과제: RubyDepre가 언어 내장 기능이 아닌 서드파티 Gem이라는 점이 수용에 가장 큰 걸림돌입니다.
- 이상적인 시나리오: Pharo처럼 언어에 내장된다면 라이브러리 개발자가 변환 규칙을 포함하여 배포하고, 사용자는 코드 실행만으로 Deprecation을 해소할 수 있어 매우 편리할 것입니다.
- 차선책: 라이브러리 개발자가 사용하지 않더라도, 사용자 스스로 자신의 코드베이스 내 Deprecation을 해결하기 위한 도구로 활용할 수 있습니다. 이는 라이브러리 메서드에 몽키 패치로 deprewrite규칙을 적용하는 방식이 될 수 있습니다.