Ruby 타입 시그니처 디자인 탐구
Ruby에 타입 시그니처를 도입하는 것은 언어의 동적 특성 때문에 복잡한 문제입니다. 저자는 다양한 접근 방식을 면밀히 검토하며 각각의 장단점을 미학적, 실용적 관점에서 평가했습니다.
기존 타입 시그니처 방식 분석
- Sorbet:
sig { params(name: String).returns(String) }- 장점: 필요한 정보를 제공하고 코드 옆에 위치하며 문법 강조 지원.
- 단점: 미학적으로 F등급. 메서드 정의의 일부처럼 느껴지지 않고,
.returns가 어색함.
- RBS (별도 파일):
def say_hello: (name: String) -> String- 장점: 미학적으로 우수.
- 단점: Ruby 코드와 별도의 파일에 작성해야 하는 한계로 C등급.
- RBS Inline (주석):
#: (name: String) -> String- 장점: 구현 바로 위에 위치하며 VSCode에서 문법 강조 지원.
- 단점: 메서드 정의의 일부처럼 느껴지지 않고, 주석이라는 근본적 한계. B등급.
- YARD:
# @param [String] name- 장점: 문서화를 위한 시그니처.
- 단점: 매우 장황하고, 메서드 정의와 동떨어져 보임. F등급.
새로운 전처리기 기반 디자인 탐색
저자는 기존 방식들의 한계를 극복하기 위해 StrictIvars에서 사용된 전처리기 기술을 활용한 새로운 아이디어를 제안했습니다.
- 전처리기 디자인 #1:
typed def say_hello(name: String)- 장점: 깔끔한 외형.
- 단점: 반환 타입 및 기본값 처리 불가. B등급.
- 전처리기 디자인 #2 (
fun키워드):fun say_hello(name: String) => String { ... }- 장점: Kotlin의
fun에서 영감을 받은 미학적 완벽성. 반환 타입이 자연스럽고 합자와 잘 어울림. S등급. - 단점: 기존 Ruby 도구(예: Zed 심볼 아웃라인)가 메서드로 인식하지 못하는 문제.
- 장점: Kotlin의
- 전처리기 디자인 #3 (
def ... = String do):def say_hello(name: String) = String do ... end- 장점: 실제
def를 사용하여 도구 호환성 확보. 인라인 메서드 정의 패턴 활용. A+등급. - 단점:
=가=>만큼 미학적이지 않고,do가 불필요하게 느껴짐.nil,true,false와 같은 반환 타입에 대한 문법적 한계.
- 장점: 실제
최종 결정 및 업데이트
def ... = nil do와 같은 특정 반환 타입의 문법적 한계로 인해, 최종적으로 fun 키워드와 do 블록을 사용하는 방식으로 회귀했습니다 (fun foo => nil do end). 이 방식은 nil 등을 포함한 모든 반환 타입을 자연스럽게 처리할 수 있습니다. 현재 개발 중인 전처리기는 Literally에서 Empirical로 이름이 변경되었으며, Strict Ivars를 포함한 다른 Ruby 개선 사항들을 통합할 예정입니다. 이 프로젝트는 Ruby에 네이티브하고 강력한 런타임 타입 검사를 제공하는 것을 목표로 합니다.