Sorbet에 RBS 주석 지원 추가: Shopify의 Ruby 개발 경험 개선

Inline RBS comments support for Sorbet

작성자
발행일
2025년 04월 23일

핵심 요약

  • 1 Shopify는 Ruby 개발 경험 개선을 위해 Sorbet의 강력한 타입 검사 기능을 유지하면서 RBS의 간결한 문법을 통합했습니다.
  • 2 기존 Sorbet의 장황한 DSL을 대체하기 위해 Ruby 3.0에 도입된 RBS를 인라인 주석 형태로 활용하여 코드 가독성과 유지보수성을 높였습니다.
  • 3 이 새로운 기능은 Sorbet의 타입 검사 파이프라인에 RBS 파싱 및 재작성 단계를 추가하여 구현되었으며, 점진적인 마이그레이션을 지원합니다.

도입

Shopify는 대규모 코드베이스의 가독성과 유지보수성 향상을 위해 Ruby용 타입 검사 도구인 Sorbet을 광범위하게 활용해왔습니다. Sorbet은 코드 안정성과 신뢰성을 높이고 리팩토링을 용이하게 하는 데 중요한 역할을 했습니다. 그러나 개발자 설문조사 결과, Sorbet의 DSL(Domain-Specific Language) 기반 문법이 때때로 장황하고 코드베이스를 복잡하게 만들 수 있다는 피드백이 있었습니다. 이러한 문제점을 해결하고 보다 사용자 친화적이며 간결한 타입 선언 방식을 제공하기 위해, Shopify는 Ruby 3.0에 도입된 타입 정의 언어인 RBS를 Sorbet에 통합하는 작업을 진행했습니다. 이 통합은 Sorbet의 강력한 타입 안전성을 유지하면서 Ruby 개발 경험을 더욱 원활하고 즐겁게 만드는 것을 목표로 합니다.

Shopify에서 Sorbet은 현재 75,000개의 파일 중 99%를 검사하고 있으며, 150만 개 메서드의 71%에 타입 시그니처가 적용되어 생산 환경에서의 오류를 크게 줄이고 있습니다. 그럼에도 불구하고, sig {}T.let과 같은 Sorbet의 DSL 문법은 복잡성을 추가하고 sorbet-runtime gem의 의존성으로 인해 런타임 성능 오버헤드가 발생하여 프로덕션 환경에서는 런타임 타입 검사를 비활성화하는 등의 한계가 있었습니다. 이러한 배경에서 Ruby 3.0의 RBS가 대안으로 부상했습니다. RBS는 .rbs 파일을 통해 타입 정의를 코드와 분리하여 간결하게 표현할 수 있지만, 75,000개에 달하는 Shopify의 파일에서 .rbs 파일을 별도로 관리하는 것은 또 다른 중복 관리 문제를 야기했습니다. 또한, 초기 RBS는 지역 변수 타이핑을 직접 지원하지 않고 대규모 코드베이스를 위한 확장 가능한 타입 체커가 부족했습니다.

Shopify 팀은 이러한 RBS의 장점과 Sorbet의 강력한 기능을 결합하여 Ruby 파일 내에 직접 타입 주석을 달 수 있는 간결한 문법을 구현하는 비전을 세웠습니다. 그 결과, #: (Array[String]) -> String과 같은 주석 기반의 RBS 문법을 개발하여 코드 가독성을 높이고 런타임 의존성을 제거했습니다. 이 기능은 Sorbet의 기존 타입 검사 파이프라인에 새로운 단계를 추가하여 구현되었습니다. 파서(parser)와 디슈가러(desugarer) 사이에 RBS 주석을 찾아 해당 AST(Abstract Syntax Tree) 노드와 연결하고, RBS 내용을 파싱하여 동등한 Sorbet sigT.let 구조로 AST 내에 직접 삽입하는 방식입니다. 이를 통해 Sorbet의 나머지 파이프라인은 변경 없이 원활하게 작동할 수 있습니다. 현재 Sorbet은 인스턴스 및 싱글톤 메서드에 대한 RBS 시그니처 주석(#: ...), 여러 줄에 걸친 시그니처(#|:), 속성 타이핑(#: String? attr_reader :nickname), 지역/전역/인스턴스/클래스 변수 및 상수에 대한 타입 지정(#: String), 타입 캐스팅(#: as String), 그리고 T.must에 해당하는 #: as !nil과 같은 다양한 RBS 주석 기능을 지원합니다. 이러한 주석은 표현식 중간에서도 타입 단언(type assertion)으로 활용될 수 있어 유연성을 제공합니다.

결론

Sorbet에 RBS 주석 지원을 추가하는 작업은 현재 진행 중이며 실험적인 기능으로 제공되고 있습니다. 이 기능을 사용하려면 Sorbet 실행 시 `--enable-experimental-rbs-signatures` 및 `--enable-experimental-rbs-assertions` 옵션을 명시적으로 활성화해야 합니다. 대규모 코드베이스를 RBS로 수동 마이그레이션하는 복잡성을 완화하기 위해 Shopify는 Spoom 도구에 기존 Sorbet 시그니처 및 단언을 RBS로 쉽게 변환할 수 있는 자동화 기능을 구축했습니다. Sorbet은 RBS 주석과 기존 `sig {}` 문법을 모두 지원하므로, 개발자들은 새로운 문법으로 점진적으로 마이그레이션할 수 있습니다. 이 통합은 Sorbet의 강력한 타입 검사 기능을 유지하면서 Ruby 개발자들에게 더욱 간결하고 읽기 쉬운 타입 선언 방식을 제공하여 전반적인 개발 경험을 향상시키는 데 기여할 것입니다. 이 작업은 최근 RubyKaigi 2025에서 발표되었으며, 곧 발표 영상이 공개될 예정입니다.

댓글 0

댓글 작성

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

아직 댓글이 없습니다

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