T‑Ruby: 런타임 오버헤드 없이 Ruby에 정적 타이핑 추가

발행: (2026년 2월 25일 오전 06:50 GMT+9)
7 분 소요
원문: Dev.to

Source: Dev.to

T‑Ruby 커버 이미지: 런타임 오버헤드 없이 Ruby에 정적 타이핑 추가

소개

정적 타이핑은 모든 규모의 코드베이스에 막대한 가치를 제공하는 강력한 도구입니다. 작은 스크립트부터 거대한 모놀리쓰까지, 그 이점은 무시하기 어렵습니다: 항상 최신 상태를 유지하는 실시간 문서, 향상된 가독성, 그리고 코드 신뢰성을 크게 높여주는 신뢰할 수 있는 안전망을 얻을 수 있습니다.

다양한 동적 언어들은 타입 문제를 해결하기 위해 각기 다른 접근 방식을 취해왔습니다. Python은 기본이지만 선택적인 타입 힌트를 도입했으며, JavaScript 생태계는 TypeScript라는 완전 별도의 언어로 나아갔습니다. Ruby 커뮤니티에서는 RBSSorbet라는 두 가지 뚜렷한 구현을 보았으며, 최근 RBS 인라인 도입과 Sorbet의 지원 덕분에 두 구현이 점차 수렴하고 있습니다.

하지만 현재 Ruby 접근 방식에도 마찰이 없습니다는 말은 할 수 없습니다. 많은 개발자에게 타입 지정은 여전히 핵심 요구사항이라기보다 개인적인 선호에 불과합니다. 타입 검사가 종종 “추가적인 것”으로 인식되기 때문에 정적 검사를 무시하거나 완전히 잊어버리기 쉽습니다.

T‑Ruby란 무엇인가?

주목받고 있는 획기적인 실험인 T‑Ruby 입니다. 일반적인 런타임 타입‑체크 시스템과 달리, T‑Ruby는 타입이 지정된 코드를 순수하고 장식이 없는 Ruby 코드로 컴파일하여 런타임 오버헤드가 전혀 없습니다. 요컨대, T‑Ruby는 Ruby 언어를 위한 TypeScript와 같은 존재이며, RBS에서 영감을 받은 코드를 작성하면 최종적으로 일반적인 표준 Ruby로 변환됩니다.

일부에서는 Crystal을 사용하자고 제안할 수도 있지만, 두 접근 방식에는 근본적인 철학 차이가 있습니다. Crystal은 자체 생태계를 가진 별도의 Ruby‑유사 언어입니다. 반면 T‑Ruby는 우리가 이미 알고 있는 Ruby에 가깝게 유지되도록 설계된 추가 레이어입니다. TypeScript가 결국 순수 JavaScript를 출력하는 것처럼, T‑Ruby도 최종 결과물이 순수 Ruby가 되도록 보장합니다.

Example: Typed HTTP Client

아래는 GitHub에서 최신 Ruby 릴리스 태그를 가져오는 간단한 HTTP 클라이언트 예시입니다. T‑Ruby를 사용하면 타입을 클래스 구조에 직접 삽입할 수 있습니다.

require "httparty"
require "json"
require "time"

class RubyVersion
  API_URL = "https://api.github.com/repos/ruby/ruby/releases/latest"

  class Response
    attr_reader :code: Integer
    attr_reader :json: Hash

    def initialize(code: Integer, json: Hash): nil
      @code = code
      @json = json
    end

    def success?: Boolean
      (200..299).include?(@code)
    end
  end

  def fetch_response: Response
    http = HTTParty.get(API_URL, headers: { 'User-Agent' => 'static-typing-demo' })
    Response.new(http.code.to_i, JSON.parse(http.body))
  end

  def self.fetch(printer: Proc<[String, String, Time], nil]): nil
    resp = new.fetch_response
    raise "HTTP #{resp.code}" unless (200..299).include?(resp.code)
    data = resp.json
    published = Time.parse((data['published_at'] || Time.now.utc.iso8601).to_s)
    printer.call((data['tag_name'] || data['name']).to_s, data['html_url'], published)
  end
end

이러한 타입을 추가함으로써 Proc의 구조를 엄격히 정의하고 시스템을 통해 전달되는 데이터가 유효함을 보장할 수 있습니다. 표준 Ruby에서는 보통 문서화나 수동 가드 절을 사용해 이러한 수준의 확실성을 얻습니다.

T‑Ruby 설정하기

  1. gem을 설치합니다:

    gem install t-ruby
  2. 설정 파일을 초기화합니다:

    trc --init

생성된 구성 파일을 통해 *.trb 파일의 소스 폴더, 컴파일된 Ruby의 대상 폴더, 그리고 RSpec이나 Minitest를 자동 실행하는 등 컴파일 후 명령을 지정할 수 있습니다.

Rails 통합 (실험적)

Rails는 특정 폴더 구조에 의존하므로 가장 깔끔한 방법은 전체 앱 폴더를 T‑Ruby 소스 디렉터리 안에 저장하는 것입니다. T‑Ruby 구문이 포함되지 않은 파일은 수정 없이 대상 폴더로 그대로 복사됩니다. 이는 Next.js와 같은 최신 JavaScript 프레임워크에서 흔히 사용하는 /src / /dist 워크플로와 동일합니다.

현재 상황 및 전망

T‑Ruby는 아직 기술 미리 보기 단계에 있습니다. 웹사이트와 문서는 다듬어졌지만 구현이 다소 변덕스러워서 공식 예제가 설치 직후 바로 실패할 수 있습니다.

이러한 거친 부분에도 불구하고 가능성은 부인할 수 없습니다. T‑Ruby를 사용해 작은 Rails 앱을 만들면서 별도의 RBS 파일 컬렉션이 필요 없게 되었습니다. 비즈니스 로직과 함께 타입을 작성하는 것이 자연스럽게 느껴지고, 컴파일 시 코드가 “타입‑정확”하다는 것을 알 수 있어 독특한 안심감을 제공합니다. 아직 프로덕션 환경에 완전히 적합하다고는 할 수 없지만, Ruby 생태계에 큰 한 걸음이라 할 수 있습니다.

원본은 my blog 에서 게시되었습니다.

0 조회
Back to Blog

관련 글

더 보기 »

스틸 뱅크 Common Lisp

Steel Bank Common Lisp(SBCL)에 대해: SBCL은 고성능 Common Lisp 컴파일러입니다. 오픈 소스·무료 소프트웨어이며, 관대한 라이선스를 가지고 있습니다. 또한…

Rails에서 타임스탬프 전환 간소화

개요 나는 종종 completed_at와 같은 timestamps를 boolean 플래그로 사용한다. 실제 boolean보다 약간 더 많은 메타 데이터를 제공하지만 UI에서는 일반적으로 …

Python에서 숫자가 정수인지 확인하기

python def is_intx: int | float | str | None: ''' x가 정수 값을 나타내면 True를 반환하고, 그렇지 않으면 False를 반환합니다. 처리 대상: - int, float, 및 숫자 문자열 등....'''