Ruby 4.0은 Ruby의 30주년 기념(2025년 12월 25일)에 출시된 주요 릴리스로, 주요 변경 사항이 아닌 커뮤니티의 30년을 기념하기 위해 출시되었습니다.
Ruby가 실제로 의미론적 버전 관리를 따르지 않는다는 사실을 알고 놀랐습니다!
대신 Matz(Ruby의 제작자)는 변경 사항이 인상적일 때 주요 버전을 늘립니다. 이 버전은 Ruby 출시 30주년을 기념하며 언어 확장 기능을 도입했습니다.

Ruby 4로 업그레이드하는 Rubyists에게 좋은 소식은 업그레이드가 상대적으로 쉬워야 한다는 것입니다. Ruby::Box와 같은 몇 가지 새로운 기능이 있습니다. 및 ZJIT , 동시성에 대한 몇 가지 개선 사항 및 대부분 이전 버전과 호환되는 몇 가지 개선 사항이 있습니다.
Ruby 4에서 변경된 사항과 원활하게 업그레이드할 수 있는 방법을 살펴보겠습니다.
Ruby::Box?가 무엇인가요?
Ruby 4.0의 가장 흥미로운 실험적 기능 중 하나는 Ruby::Box입니다. , Ruby 프로세스 내에 격리된 네임스페이스 또는 "컨테이너"(Docker 컨테이너와 혼동하지 말 것)를 도입합니다.
이는 본질적으로 Ruby 프로세스 내에서 격리된 Ruby 세계를 분리하는 방법입니다. 새로운 Ruby::Box을 생성할 때 , 해당 Box 내부에 로드하는 모든 클래스, 모듈, 전역 변수, 상수 또는 심지어 C 확장까지 여기에 국한됩니다.
이는 언어 수준의 경량 가상화와 같습니다. 각 Box는 자체 상태를 가지며 다른 Box나 기본 환경에 정의가 유출되지 않습니다.
실험적이기 때문에 가장자리가 거칠거나 불안정할 수 있습니다. 성능 오버헤드를 고려해야 합니다. 사물을 격리하는 것은 무료가 아니기 때문에 핵심 팀에서는 의도적으로 이를 선택하도록 했습니다.
Ruby 4.0부터 Box는 진정한 병렬 실행을 즉시 제공하기 위한 것이 아닙니다. 이는 보다 스마트한 코드 로딩을 위한 기반을 마련하고 보다 의미 있는 코드로 발전할 수 있습니다. 저는 Ruby가 이렇게 흥미로운 방식으로 발전하는 것을 보게 되어 기쁩니다. Ruby Box를 사용하려면 먼저 환경 변수를 활성화해야 합니다:
RUBY_BOX=1
ZJIT가 중요한 이유
Ruby 4.0에는 YJIT의 후속 제품으로 개발된 새로운 Just-In-Time 컴파일러인 ZJIT가 도입되었습니다. 계속 세고 있다면 MRI에는 이제 두 개가 있습니다. JIT 컴파일러. ZJIT는 YJIT와 다르며 동시에 개발되고 있습니다. 이미 YJIT를 사용하고 있다면 전환할 필요가 없습니다.
YJIT 요약
YJIT(“Yet Another JIT”)는 Shopify에 의해 구축되었으며 Ruby 3.1에 도입되었습니다. Lazy Basic Block Versioning 접근 방식을 사용하여 즉석에서 작은 코드 덩어리(기본 블록)를 컴파일하고 런타임 유형에 따라 특수화합니다.
YJIT는 상대적으로 추가하기 쉬우면서도 많은 Ruby 앱의 속도를 크게 향상시키는 것으로 입증되었습니다. Rust로 작성되었으며 최근 Ruby 버전에서는 기본/기본 JIT였습니다.
ZJIT의 차이점
ZJIT는 보다 전통적인 방법 기반 JIT 전략을 취합니다. 작은 블록을 단편적으로 컴파일하는 대신 ZJIT는 SSA(Static Single Assignment) 중간 표현과 보다 일반적인 컴파일러 파이프라인을 사용하여 더 큰 단위(전체 메소드 또는 더 큰 코드 청크)를 컴파일합니다.
이는 기여자가 더 쉽게 이해하고 개선할 수 있도록 하는 "교과서" JIT 컴파일러와 비슷하게 설계되었습니다.
Ruby 핵심 팀은 ZJIT의 두 가지 목표가 Ruby의 장기적인 성능 한도를 높이고(YJIT가 할 수 있는 것보다 더 고급 최적화를 활성화하여) 커뮤니티에서 JIT를 더 쉽게 해킹할 수 있도록 만드는 것이라고 명시적으로 밝혔습니다.
Ruby 4.0에서 ZJIT 활성화
ZJIT를 사용할 수 있지만 Ruby 4.0에서는 기본적으로 활성화되어 있지 않습니다.
이를 시도하려면 시스템에 Rust 1.85 이상이 설치된 Ruby를 빌드해야 합니다. JIT 코드는 Ruby 바이너리의 일부이지만 이를 빌드하려면 Rust가 필요합니다. 그런 다음 '--zjit' 플래그와 함께 Ruby를 실행하여 ZJIT를 사용할 수 있습니다.
JIT를 기본값으로 놔둬도 여전히 YJIT의 이점을 누릴 수 있습니다(자체적으로 개선됨). --rjit을 사용하고 있었다면 플래그가 이번 릴리스에서는 제거되었음을 알 수 있습니다.
Ruby 4에서는 Ractors가 일부 개선되었습니다.
Ruby 3.0에서는 병렬 처리를 위한 실험적 기능인 Ractors를 도입했습니다. Ractor를 사용하면 단일 프로세스에서 여러 Ruby 인터프리터(코드를 실행하는 시스템의 일부)를 실행하여 일반적으로 Ruby를 한 번에 단일 스레드로 제한하는 GIL(Global Interpreter Lock)을 해결할 수 있습니다. 저는 Ractors를 사용해 본 적이 없지만 이에 대한 지속적인 투자는 Ractors가 Ruby의 미래에 중요하다는 분명한 신호입니다.
Ruby 4.0에서 Ractor는 여전히 실험적이라고 표시되었지만 주류 사용성에 더 가까워지기 위해 몇 가지 주요 개선 사항과 API 변경이 이루어졌습니다.
Ractors를 사용해 본 적이 있다면 메시지를 보내고 받는 것이 약간 투박하다는 것을 알 것입니다. Ruby 4.0은 기존 API를 더욱 강력한 Ractor::Port로 대체합니다. 메커니즘. Ractor::Port 본질적으로 Ractor가 값을 교환하는 데 사용할 수 있는 파이프 또는 채널입니다. 이제 각 Ractor에는 기본 포트(Ractor.current.default_port)가 있습니다. ), 사용자 정의 포트 개체를 생성하여 전달할 수도 있습니다.
Ractors에 대한 변경 사항은 일부 주요 변경 사항이 있음을 의미합니다. 특히 Ractor.yield 및 Ractor#take 삭제되었습니다.
내부적으로는 Ruby 4.0의 Ractor 구현이 더 나은 성능과 안전성을 위해 조정되었습니다. Ractor 간의 공유 상태를 줄였습니다. Ractor 간의 공유 상태가 적다는 것은 실수로 격리를 깨뜨릴 가능성이 낮다는 것을 의미하며 멀티 코어 시스템에서 CPU 캐시 활용도가 향상됩니다.
Ractor는 이제 스레드나 프로세스만큼 널리 사용되지는 않지만 더 잘 확장되고 더 빠르게 실행되어야 합니다.
*.nil Ruby 4의 변경 사항
스플래팅 nil 더 이상 nil.to_a에 전화하지 않습니다. 루비 4.0에서.
이전 Ruby 버전에서는 arr = [*nil]와 같은 작업을 수행합니다. nil.to_a로 전화하겠습니다 비하인드 스토리([] 반환) ), 따라서 빈 배열을 얻게 됩니다. 이것은 약간 마술적이고 일관성이 없었습니다. (왜 *nil은 빈 배열처럼 행동하나요?).
Ruby 4.0에서는 이 이상한 동작이 사라졌습니다. 표시 사용(* ) nil 않습니다 to_a 호출 . 본질적으로 "표시할 내용 없음"으로 처리됩니다. 이 변경으로 인해 이중 표시 **nil 방식과 일치하게 됩니다. nil.to_hash에 전화하지 않습니다 , 이는 Ruby 3.4에서 도입되었습니다.
Ruby 4의 줄 시작 부분에 있는 논리 연산자
이것은 많은 Rubyist를 웃게 만들 다소 작은 구문 개선입니다!
이제 &&을 입력할 수 있습니다. , || , and 또는 or 처음에 이전 줄의 부울 표현식을 계속하려면 한 줄을 사용하세요. 예를 들어 다음과 같이 쓸 수 있습니다:
if user_signed_in?
&& user.admin?
&& feature_enabled?
perform_admin_task
end
와 같습니다.
if user_signed_in? &&
user.admin? &&
feature_enabled?
perform_admin_task
end
이것이 아직 동일하지 않다는 것이 조금 이상합니다. 그래서 이번 업데이트가 기쁘네요.
Ruby 4의 일부 클래스 업데이트
Ruby 4.0에는 핵심 클래스에 대한 몇 가지 작은 변경 사항과 개선 사항도 포함되어 있습니다.
먼저 Set 클래스는 이제 내장 핵심 클래스이므로 require 'set' 없이 사용할 수 있습니다. . 이는 set/sorted_set.rb 제거와 함께 제공됩니다. .
이제 Pathname도 마찬가지입니다. , 핵심반으로 승격되었습니다.
새로운 Array도 있습니다. 방법! 이번 릴리스에서는 Array#find의 성능이 향상되었습니다. , 단순한 선형 검색보다 더 지능적으로 배열을 검색합니다. Array#rfind도 도입되었습니다. - 오타가 아닙니다! 이 메소드는 조건과 일치하는 마지막 요소를 찾습니다. 배열에 있습니다.
Ruby 4에는 몇 가지 새로운 수학 메서드, 내부 검사 제어, Enumerator도 추가되었습니다. 개선, 그리고 더! 전체 개선 목록을 보려면 공식 문서를 꼭 확인하세요.
루비 4로 업그레이드하는 방법
프로덕션 앱에서 Ruby 버전을 업그레이드하는 것은 항상 주의해서 수행해야 하지만 Ruby 3.4를 사용하는 경우 이것이 가장 쉬운 업그레이드 중 하나입니다 경험해 보셨을 겁니다.
안전한 전환을 위한 몇 가지 팁은 다음과 같습니다.
출시 노트
먼저 공식 릴리스 노트를 읽어보세요! 공식적인 지원 중단 알림을 다시 확인하세요. 그러면 안 됩니다 여기서는 놀랄 일이 아닙니다. Ruby 3.4에서는 향후 지원 중단에 대해 경고했어야 합니다.
지원 중단 경고
Ruby 인터프리터의 지원 중단 경고를 무시했다면 언어를 업데이트하기 전에 해당 경고를 해결하세요.
기준 테스트
다음으로, 좋은 테스트를 받았는지 확인하세요. 이렇게 하면 앱의 동작이 변경되지 않았다는 확신을 갖게 됩니다. 아무것도 없는 경우 이제 최소한 중요한 경로를 커버하기 위해 테스트에 투자할 절호의 기회입니다.
번들러 업데이트
다음에 Bundler를 업데이트하는 것이 좋습니다. 최신 버전을 사용하고 나면 bundle install를 실행하세요. 오류나 경고를 확인하세요.
Ruby 버전을 올리세요
이제 새 버전의 Ruby를 설치하고 전환할 수 있습니다. rbenv와 같은 Ruby 버전 관리자 또는 asdf Ruby 세계에서는 로컬 버전을 제어하는 데 인기가 있습니다. 앱이 Docker에서 실행되는 경우 Dockerfile에서 Ruby 버전을 업데이트하는 것이 좋습니다. 앱이 Docker 없이 일부 플랫폼에서 실행되는 경우 그곳에서 Ruby 버전을 업데이트하는 것이 좋습니다.
Gemfile에서 Ruby 4.0으로 업그레이드
Gemfile에서 Ruby 버전을 업데이트하세요(ruby로 잠긴 경우). 지시문) bundle install를 실행합니다. 마지막으로 한번 더.
테스트 실행
마지막으로 테스트를 실행해 보세요! 손상된 것이 없으면 애플리케이션에서 중요한 경로를 실행하여 더욱 큰 자신감을 얻으십시오. 업그레이드를 출시하기 전에 실제로 알 수 있도록 Honeybadger와 같은 예외 모니터링 서비스를 사용해 보세요. Ruby 4로의 업그레이드로 인해 사용자에게 문제가 발생하는 경우
이 단계를 따르면 Ruby가 제공하는 최고의 기능에 대한 최신 정보를 비교적 고통 없이 경험하게 될 것입니다. 테스트를 실행할 때 Ruby의 30번째 생일을 축하하는 것을 잊지 마세요!