Zeitwerk: 루비 프로젝트를 위한 자동 로딩의 미래

Xavier Noria, keynote, "Zeitwerk: A Retrospective"

작성자
EuRuKo
발행일
2025년 01월 13일

핵심 요약

  • 1 Zeitwerk는 Ruby 및 Rails의 자동 로딩, 즉시 로딩, 코드 리로딩을 담당하는 핵심 Gem입니다.
  • 2 기존 자동 로더의 한계를 극복하고, 'require' 의존성을 자동 관리하여 개발 편의성을 높였습니다.
  • 3 투명성, 견고한 API 디자인, 버그 없는 소프트웨어 추구를 통해 루비 생태계에 기여하고 있습니다.

도입

발표자는 컨퍼런스 오프닝을 맡은 영광을 표하며, Ruby 및 Rails 프로젝트의 핵심적인 자동 로딩 기능을 제공하는 Zeitwerk Gem을 소개합니다. 이 발표는 Zeitwerk의 개발 배경, 기능, 설계 철학, 그리고 미래 방향에 대한 심도 깊은 논의를 담고 있습니다.

Zeitwerk는 Ruby 프로젝트에서 require 문 없이 코드를 사용할 수 있게 하는 자동 로딩(Autoloading), 코드를 미리 로드하는 즉시 로딩(Eager Loading), 그리고 코드 변경 시 자동으로 리프레시하는 리로딩(Reloading) 기능을 제공하는 필수적인 Ruby Gem입니다. 특히 Ruby on Rails 프레임워크에서 이 핵심 기능들을 담당하고 있습니다. 기존 Rails의 const_missing 기반 자동 로더는 컨텍스트 정보 부족으로 인한 문제와 require의 전역적 부작용으로 인한 의존성 관리의 어려움을 겪었습니다. Zeitwerk는 이러한 근본적인 한계들을 해결하여 개발자가 require 관련 문제에 대한 고민 없이 효율적으로 코드를 작성하고 관리할 수 있도록 자동화된 솔루션을 제공합니다.

2019년 첫 안정 버전 출시 이후, Zeitwerk는 Shopify와 GitHub와 같은 세계 최대 규모의 Rails 애플리케이션에 성공적으로 도입되며 그 견고함과 효율성을 입증했습니다. 초기 Rails 6.0 및 6.1 버전에서는 기존 로더와 함께 제공되어 사용자들의 원활한 마이그레이션을 지원했으며, 현재는 약 600개 이상의 Gem에서 사용되고, 하루 약 50만 건의 다운로드를 기록하는 등 Ruby 생태계에 광범위하게 기여하고 있습니다. Zeitwerk의 핵심 설계 목표 중 하나는 ‘투명성’으로, 사용자 코드가 Zeitwerk의 존재를 인지할 필요 없이 일반적인 Ruby 프로젝트처럼 보이도록 설계되었습니다.

발표자는 Zeitwerk의 API 디자인 철학으로 네 가지 핵심 원칙을 강조합니다. 첫째, ‘사용성’을 최우선으로 하여 클라이언트 코드가 직관적이고 ‘옳게 보이도록’ 설계합니다. 둘째, ‘좋은 인터페이스는 사용자 실수를 디자인으로 방지’합니다. 예를 들어, Inflector API는 불필요한 정보(파일 확장자)를 제거하고 이미 알고 있는 컨텍스트(부모 디렉토리의 네임스페이스)를 활용하여 사용자에게 더 간결하고 실수할 여지가 적은 인터페이스를 제공합니다. 셋째, ‘좋은 인터페이스는 최적의 관행으로 유도’합니다. 일관된 명명 규칙(예: ‘API’의 대소문자 통일)을 따르도록 유도하는 간결한 API를 제공합니다. 넷째, ‘좋은 인터페이스는 지식 비대칭성(Knowledge Asymmetries)을 반영’합니다. 모든 사용 사례가 대칭적이지 않으므로, 일반적인 사용 사례에 대해서는 간결하고 특화된 API를 제공하여 편의성을 높입니다(예: 디버깅을 위한 loader.log!).

또한, 발표자는 Ruby에서 ‘공개 인터페이스’의 정의가 단순히 public 가시성을 가진 메서드를 넘어선다는 점을 강조합니다. 라이브러리 내부적으로는 public이어야 하지만 외부 사용을 의도하지 않는 메서드들이 존재하며, Zeitwerk는 internal 매크로를 통해 이러한 내부 메서드를 명확히 표시하여 사용자들이 의도치 않게 프라이빗 API를 사용하는 것을 방지합니다. 더 나아가, 소프트웨어 오류가 불가피한 것이 아니라는 메시지를 전달하며, TeX나 Elixir처럼 버그가 적거나 없는 소프트웨어가 존재함을 예시로 들고, Zeitwerk 또한 버그 보고가 거의 없음을 강조합니다. 개발자들에게 버그를 당연하게 여기지 말고, 높은 수준의 품질과 탁월함을 추구하도록 독려합니다.

Zeitwerk의 향후 주요 목표는 Ruby의 상수 해석 방식과 100% 일치하는 자동 로딩을 완벽하게 제공하는 것입니다. 현재 Zeitwerk는 TracePoint를 활용하여 ‘명시적 네임스페이스’의 순환 참조 문제를 해결하고 있지만, Class.new와 같은 일부 엣지 케이스에서는 여전히 한계가 있습니다. Ruby 3.2에 도입된 Module#const_added API를 활용하면 이 마지막 엣지 케이스까지 해결하여 완벽한 자동 로더를 구현할 수 있을 것으로 예상되며, 이는 Zeitwerk 3의 핵심 목표가 될 것입니다.

결론

Zeitwerk는 기존 자동 로더의 한계를 극복하고, 견고한 설계와 지속적인 개선을 통해 Ruby 개발 경험을 향상시키고 있습니다. 사용자 편의성을 최우선으로 하는 API 디자인 철학을 바탕으로, 궁극적으로 Ruby의 상수 해석 방식을 완벽하게 따르는 자동 로더를 목표로 하며 Ruby 생태계에 중요한 기여를 하고 있습니다.

댓글 0

댓글 작성

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

아직 댓글이 없습니다

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