1P by GN⁺ 2시간전 | ★ favorite | 댓글 3개
  • Ruby는 가장 빠르거나 유행하는 언어는 아니지만, 15년 넘게 여러 언어를 거친 뒤에도 일을 즐기고 싶을 때 다시 선택되는 언어로 남아 있음
  • refinements, Forwardable, SimpleDelegator, Object#then, Kernel#tap, 번호 매개변수는 작은 문법 편의와 읽기 쉬운 흐름을 제공함
  • 표준 라이브러리의 Thread::Queue, json, csvRuboCop, Ruby LSP는 작은 gem과 복잡한 설정 없이도 실용적인 개발 환경을 유지하게 해 줌
  • Ruby 3.x의 YJIT와 4.x의 ZJIT는 CPU 집약 작업 격차를 줄이고 있으며, 간단한 Fibonacci 비교에서 Ruby with ZJIT가 Go의 2~3배 이내였음
  • Rust·Go·Python이 더 적합한 영역도 있지만, 웹 앱·백그라운드 처리·내부 도구에서는 개발자 행복과 빠른 반복 속도가 Ruby의 강점으로 남아 있음

Ruby가 편하게 느껴지는 언어적 이유

  • Ruby는 가장 빠르거나 가장 유행하는 언어는 아니지만, 15년 넘게 여러 언어를 오간 뒤에도 실제로 일을 즐기고 싶을 때 다시 선택하게 되는 언어로 남아 있음
  • refinements는 제한된 범위에서만 클래스를 열 수 있게 해, 전체 네임스페이스를 오염시키지 않고 파일이나 블록 안에 작은 문법 편의를 추가할 수 있음
    • 테스트 헬퍼나 큰 코드베이스의 내부 DSL에 잘 맞음
    • using QuotingRefinement를 호출한 위치에서만 "hello".quote 같은 메서드를 사용할 수 있음
  • 표준 라이브러리의 ForwardableSimpleDelegator는 래퍼 메서드를 직접 쓰거나 추가 gem을 끌어오지 않고도 깔끔한 위임을 가능하게 해 줌
    • Rails를 이미 쓰는 경우 Active Support의 delegate가 더 편할 수 있지만, 핵심 Ruby 버전은 일반 스크립트를 가볍게 유지해 줌
  • Object#thenKernel#tap은 중간 변수를 만들지 않고도 작업을 위에서 아래로 읽히는 체인으로 연결하게 해 줌
    • User.new(params).tap { ... }.then { ... }.save처럼 생성, 로깅, 정규화, 저장 흐름을 이어 쓸 수 있음
  • Ruby 2.7 이후의 번호 매개변수는 짧은 콜백에서 잡음을 줄여 줌
    • items.map { _1.price * 1.1 }처럼 블록 인자를 명시하지 않아도 됨
  • fiber scheduler는 이벤트 루프를 연결했을 때 순차 코드처럼 보이는 동시성 코드를 작성할 수 있게 해 줌
    • Fiber.schedule do ... end 형태로 다른 fiber와 협력하는 코드를 표현함

도구, 성능, 생태계의 현재 모습

  • Shopify의 Ruby LSP는 최소 설정으로 에디터 통합을 제공하며, 점진적 타입 적용을 위한 Steep이나 RBS와 함께 잘 동작함
  • RuboCop은 다른 생태계에서 보이는 의식적인 절차 없이도 스타일을 일관되게 유지하게 해 줌
  • 표준 라이브러리는 흔한 작업을 위해 여러 작은 gem을 추가하지 않아도 되는 조용한 강점으로 남아 있음
    • 큐가 필요하면 Thread::Queue를 사용할 수 있음
    • JSON이나 CSV 파싱은 jsoncsv 라이브러리가 대부분의 실제 사용 사례를 큰 절차 없이 처리해 줌
  • Ruby 3.x의 YJIT에 이어 4.x 시리즈에는 ZJIT가 들어오고 있음
    • ZJIT는 같은 기반 위에서 더 공격적으로 동작하는 JIT이며, 더 뜨거운 실행 경로를 효과적으로 컴파일함
    • 초기 수치상 CPU 집약 작업에서 Ruby와 큰 격차를 보이던 언어들과의 차이가 의미 있게 줄어듦
    • CRuby ZJIT는 Ruby 메인 저장소에서 개발되고 있음
  • 같은 머신에서 재귀 Fibonacci 구현을 비교한 간단한 벤치마크에서는 Ruby with ZJIT가 Go의 2~3배 이내였고, 해당 사례에서 최적화된 Rust와도 크게 떨어지지 않았으며, Python with pypy는 뒤처졌음
    • 마이크로벤치마크에는 한계가 있지만, JIT가 최적화할 시간이 생긴 따뜻한 코드 경로에서는 실제 애플리케이션도 더 큰 이득을 볼 수 있음
  • Rust와 비교하면 Ruby는 비즈니스 로직의 반복 속도에서 강점이 있음
    • Rust에서는 런타임에는 명확한 일에도 borrow checker와 씨름하는 시간이 생길 수 있음
    • Go는 동시성 기본 요소가 뛰어나지만, 최근까지 generics가 없었고 다소 경직된 오류 처리 때문에 간단한 스크립트가 필요 이상으로 무거워질 수 있음
    • Python은 가장 가까운 정신적 사촌이지만, 특히 클래스와 데코레이터 주변에서 같은 고수준 아이디어를 표현하는 데 더 많은 보일러플레이트가 필요함
  • 모델에 코드를 넣을 때 토큰 효율성도 Ruby의 실제 장점으로 작동함
    • do/end나 중괄호로 블록을 표현하고, 가독성이 허용되면 메서드 호출에 괄호가 거의 필요 없음
    • 해시와 키워드 인자가 일급 기능이며 간결해, 구조적 잡음이 많은 언어보다 같은 컨텍스트 창에 더 많은 실제 로직을 넣을 수 있음
  • Ruby의 메타프로그래밍 유틸리티는 작고 읽기 쉬운 API를 만들기 좋음
    • define_method, class_eval, missing method 가로채기 같은 기능으로 코드 생성 단계 없이 표현력 있는 API를 만들 수 있음
    • dry-rbaasm 같은 라이브러리는 이 기능을 절제해서 사용해 깔끔한 상태 머신과 검증 계층을 제공함
  • 커뮤니티 도구와 배포 흐름도 성숙해졌음
    • byebugpry는 다른 곳에서 써 본 많은 디버거보다 더 유연하게 느껴짐
    • 백그라운드 작업에서는 solid_queuegood_job이 단순해, 구현 전체를 한 오후에 이해할 수 있을 정도로 접근 가능함
    • Kamal은 많은 사람에게 오래된 capistrano식 절차를 대체했으며, 실제로 작은 팀을 운영하는 사람들이 만든 도구처럼 느껴짐
  • Ruby가 모든 작업에서 Rust나 Go를 이긴다는 뜻은 아니며, Rust나 Go가 더 적합한 영역도 있음
  • 웹 애플리케이션, 백그라운드 처리, 내부 도구라는 넓은 중간 영역에서는 Ruby가 과도한 의식이나 잦은 컨텍스트 전환 없이 개발자 행복을 계속 제공함
  • 작은 편의와 언어의 전체적인 감각은 10년이 넘은 뒤에도 먼저 손이 가게 만드는 요소로 남아 있으며, 새로운 JIT 작업과 꾸준한 언어 개선이 그 이유를 더 강화함

댓글과 토론

루비를 좋아하고 많이 쓰기도 했지만 지금은 딱히 써야할 이유를 찾을수가 없네요.

Ruby는 세계적으로는 많이 쓰이는 편이지만 한국에서는 유독 안쓰여서 신기해요.

Lobste.rs 의견들
  • no ceremony RuboCop”이라는 표현에는 동의하기 어려움
    RuboCop은 어떤 cop을 고르고 조정할지, 최근 업데이트로 추가된 새 cop을 켤지 말지 논의하는 과정이 꽤 많음
    StandardRB가 훨씬 더 의식 없는 접근에 가깝지만, 결국 그것도 하나를 골라야 함
    린트가 언어에 내장된 언어들은 Ruby보다 훨씬 덜 번거롭고, 사소한 스타일 논쟁도 적음

    • 10년쯤 전에 Sidekiq 코드베이스에 Standard를 골랐고, 한 번도 후회한 적 없음
      제약은 오히려 자유를 줌
    • 그냥 기본값을 전부 쓰면 안 되나?
      린터 설정 자체에 대체로 반대하는 편이고, 이런 결정은 커뮤니티 기본값에 맡기고 싶음
    • 솔직히 이 부분은 생각이 왔다 갔다 함
      한편으로는 RuboCop 기본값이 충분히 괜찮으니 코딩 스타일을 더 쪼개기보다 따르고 함께 발전시키는 게 맞다고 봄
      다른 한편으로는 가끔 너무 의견이 강해서, standard.rb 같은 것이 필요해 보이기도 함
      Ruby를 배우거나 다시 돌아오려는 사람이 쾌적하게 코드를 쓰기 위해 수많은 gem을 상대하지 않아도 되는 관점에서 글을 썼음
    • 100% 동의함
      Go가 나왔을 때 하나의 공식 포맷팅 시스템을 제공한 건 정말 잘한 일이라고 봤음
      뇌는 패턴 매칭 기계라서 익숙해지면 그냥 넘어가게 되는데, 선택지가 있으면 불편함을 느끼고 모두가 이쪽저쪽으로 끌리게 됨
      문제는 RuboCop도 Standard도 Ruby에서 그런 권위를 가질 수 없다는 것임
      그 권위는 코어 팀에서 나와야 하지만, Ruby 철학에 어긋나기 때문에 일어나지 않을 가능성이 큼
      내 프로젝트에서는 RuboCop cop을 전부 끄고 일부만 켬
      작은따옴표가 최고임 😀
    • 그 부분에서 나도 잠깐 멈칫했음
      다른 글에서도 이 점을 짚는 듯함: https://caio.ca/blog/coding/my-complicated-relationship - “The Wild West of Code Formatting”
      “단순한 내장 솔루션이 아니다. 설정 가능한 cop이 수백 개라 어떤 규칙을 켤지 끝없는 논쟁으로 이어진다”는 식임
  • 대체로 동의하지만, refinements가 첫 예시인 건 조금 아쉬움
    좋아하는 이유는 이해하지만, 소시지가 어떻게 만들어지는지 모르는 편이 나은 부류에 가까움
    의미론이 너무 까다로워서 도입된 지 10년이 지난 지금도 MRI에서 골치 아픈 버그를 계속 찾고 있음
    예를 들면 최근 2주 사이에도 https://bugs.ruby-lang.org/issues/22071https://bugs.ruby-lang.org/issues/22058 가 있었음
    성능 측면에서도 많은 최적화를 어렵게 만드는 편이고, 지금 boxes에서도 비슷한 일이 다시 벌어지고 있음

    • boxes 아이디어는 모든 것이 수십 년 동안 같은 전역 이름공간에 살아온 언어에 뒤늦게 끼워 넣기 어려워 보임
      구현 수준에서도 아직 숨어 있는 버그가 많을 테고, 라이브러리 쪽에서도 마찬가지일 것 같음
      이제 Ruby를 많이 쓰지는 않지만, 이게 어떻게 자리 잡을지 궁금함
      재미있어 보임
  • 이 글은 내 “Returning to Rails” 글[1]에서의 경험과도 많이 겹침
    확증편향일 수도 있지만, Rails 코드의 아름다움을 다시 발견하거나 새삼 인정하는 사람이 더 많아지는 듯 보임
    다만 음악이나 예술 취향이 10대 후반~20대에 굳어진다는 현상도 떠오름
    Rails의 “황금기”에 Ruby를 처음 만났던 사람들이, Rails 3와 Capistrano가 있던 시절을 장밋빛 안경으로 되돌아보는 건 아닐까 싶음
    그때 Ruby “shop”에 깊이 들어가 있었고 주변도 Rails 개발자들뿐이라 어디에나 Ruby가 있는 것처럼 느꼈음
    그런데 lobste.rs 스레드[2]에서 Ruby는 사실 언제나 꽤 틈새 언어였다는 견해를 보니, 그런 영향도 있었을 수 있음
    그래도 Ruby는 여전히 집처럼 느껴지고, 내 머리가 돌아가는 방식 그대로 동작하는 것 같음
    번역 과정이 거의 없고, 놀랄 일도 없고, 형식적인 논문을 쓰기보다 친구와 대화하는 느낌임
    이렇게 딱 맞는 언어는 아직 못 찾았고, 이게 전부 “요즘 애들은 말이야”식 사고 때문만은 아니라고 봄
    어쨌든 이렇게 오래 살아남아 있는 게 기쁨
    그리고 “tap / new” 체인을 알려줘서 고마움
    그 구조가 너무 아름답고 유용해서 잠깐 멈춰 보게 됐고, 꼭 써보게 될 것 같음
    PS - 주제와 직접 관련은 없지만, 홈페이지의 AI 아바타가 좀 섬뜩함
    “이 글을 봇이 썼나?” 같은 불쾌한 골짜기 느낌을 강하게 줌
    그런 걸 볼 때마다 내가 실제 인간과 대화하고 있는지 잠깐 고민하게 됨
    [1]=https://www.markround.com/blog/2026/03/05/returning-to-rails-in-2026/
    [2]=https://lobste.rs/s/jreqtw/returning_rails_2026

    • 나는 진짜 사람이라고 확실히 말할 수 있음
      실제 사진을 공개하고 싶지 않을 뿐이고, 그 아바타는 실제로 아는 사람들이 알아볼 만큼은 비슷함
  • Ruby 3.4에는 it 블록 매개변수가 추가됐고, 예시의 _1 대신 쓸 수 있음

    items.map { it.price * 1.1 }  
    

    https://rubyreferences.github.io/rubychanges/3.4.html/…

    • it을 언급하는 걸 잊었음
      비교적 최근 기능이라 그런지, 반복자에서 it을 치는 데 손에 밴 습관이 도무지 붙지 않음
  • Ruby로 코드 쓰는 건 정말 좋아했지만, 테스트 부담이 너무 커졌음
    언어에 타입 안전성을 어느 정도 더하면 도움이 될 줄 알았는데, #{last_job}에서 코드베이스에 Sorbet을 넣자 코드 작성의 추진력과 재미가 완전히 죽었음
    인기 없는 생각일 수 있지만, Sorbet 같은 것이 존재한다는 사실 자체가 Ruby에 대한 나쁜 냄새에 더 가깝다고 봄
    Ruby 자체는 강력하고 재미있는 언어지만, 사람들이 원래 설계되지 않은 작업에 쓰기 시작했고, 그 과정에서 언어의 안티기능을 보완하려고 도구를 덧붙이기 시작했음
    이제는 모든 줄이 지루한 고역처럼 느껴졌고, 실제 코드를 쓰는 시간보다 여러 빌드·테스트·린트 도구를 기다리는 시간이 훨씬 많았음
    여기에 과도하게 설계된 빌드와 배포 과정까지 더해져서, 기본적인 일조차 오래 걸리고 작업이 괴로워졌음
    2012년쯤의 Ruby 세계가 많이 그리움
    돌이켜보면 정말 좋은 시절이었음

    • 경험상 더 적합한 언어는 무엇이었나?
      “원래 설계되지 않은 작업”이라고 한 건 큰 Rails 애플리케이션을 뜻한다고 이해했음
  • 10년 만에 Ruby로 돌아왔는데, “AI” 시대에는 눈앞을 스쳐 지나가는 코드를 실제로 이해하고 LLM을 조종하거나 멈출 수 있다는 점이 유용함
    더 장황한 언어에서는 이게 더 어려움

  • Ruby가 그립고, 더 나아가 일상적인 프로덕션에서 그런 언어가 가능하다는 사실 자체가 그리움
    그것은 희망이었고, 아니 희망 그 자체였음
    적어도 나에게는 오랫동안 그랬음

    • 무슨 일이 있었나?
  • AI가 대충 만든 글처럼 읽힘
    최근의 다른 블로그 글들도 비슷함

    • 난 그런 조짐을 느끼지 못했음
      어떤 단서 때문에 그렇게 봤나?
      이 사이트에서 AI 생성 저품질 글을 지적하는 건 좋지만, 오탐을 피하고 왜 그렇게 생각하는지 정확히 말할 필요가 있음
    • 나에게는 AI가 대충 만든 글처럼 읽히지 않았음
      왜 그렇게 생각했나?
      이런 경고 자체는 좋지만, 이유를 함께 말해주는 편을 훨씬 선호함
  • 커리어 초기에 Ruby로 일했던 기억이 좋음
    Ruby에는 정말 기분 좋은 무언가가 있음
    그런데 아마 작년에 최근 Ruby를 조금 썼을 때는 웹 기반 표준 라이브러리 문서를 탐색하기 어렵다고 느꼈음
    나만 그런가? ruby-lang.org 문서의 대안이 있을까?

  • 이 글은 좀 이상하게 느껴짐
    Ruby로 프로젝트 하나, SDK 하나를 작성할 기회가 있었는데, 다시는 Ruby를 쓰고 싶은 마음이 전혀 들지 않았음