
Ruby 4.0 é lançado com Ruby Box, ZJIT e avanços de performance
O Ruby 4.0.0 foi lançado em 25 de dezembro de 2025 e marcou uma das atualizações mais relevantes da linguagem nos últimos anos. A nova versão trouxe Ruby Box, ZJIT, melhorias importantes de performance, avanços em Ractor e mudanças que afetam diretamente quem desenvolve aplicações Ruby e Rails.
Na terceira semana do Ruby Insights, uma história se destaca acima de todas as outras no ecossistema: o lançamento do Ruby 4.0.0, em 25 de dezembro de 2025. Matz escolheu o número 4.0 para marcar os 30 anos do Ruby, e não para sinalizar uma onda de breaking changes, mas esta está longe de ser uma atualização incremental. A versão traz o Ruby Box, um novo compilador JIT chamado ZJIT, uma API do Ractor reformulada, uma longa lista de otimizações no runtime e no GC e uma rodada de limpeza que os times devem planejar antes de atualizar.
Ruby Box: Isolamento Dentro de um Único Processo
O Ruby Box é um recurso experimental, habilitado pela variável de ambiente RUBY_BOX=1 e exposto pela classe Ruby::Box. O código carregado dentro de uma box fica nela: monkey patches, alterações em variáveis globais e de classe, definições de classes e módulos e até bibliotecas Ruby e nativas carregadas ficam isolados das outras boxes.
As release notes listam os casos de uso que o time core tem em mente: rodar testes que fazem monkey patch em comportamentos do core sem vazar para outros testes, rodar duas boxes da aplicação lado a lado para deploy blue-green dentro de um único processo do app server e comparar as respostas entre as dependências atuais e as atualizadas antes de confirmar um upgrade. A Box também deve se tornar a base de baixo nível para uma futura API de "pacotes". Para quem desenha arquiteturas Ruby ou opera sistemas Ruby, essa é uma das adições mais interessantes ao runtime em anos. Como ainda é experimental, trate-a como algo para explorar, não para colocar em produção.
ZJIT: A Próxima Geração Depois do YJIT
O ZJIT é um novo compilador JIT baseado em métodos, desenvolvido como a próxima geração do YJIT. Ele compila unidades de código maiores por meio de uma representação intermediária em SSA, o que eleva o teto de otimização, e seu design mais convencional pretende facilitar contribuições de fora do time. Compilar o Ruby com ZJIT exige Rust 1.85.0 ou mais recente, e você o ativa com --zjit (ou RubyVM::ZJIT.enable em tempo de execução).
A ressalva é importante: na 4.0.0, o ZJIT é mais rápido que o interpretador, mas ainda não tão rápido quanto o YJIT, e o time core recomenda não usá-lo em produção por enquanto. A meta declarada é um ZJIT que supere o YJIT e esteja pronto para produção no Ruby 4.1. Para apps Rails hoje, o YJIT continua sendo a escolha certa.
Um Runtime Mais Rápido Sem Mexer no Seu Código
Além do JIT, a 4.0 traz melhorias no runtime que fazem diferença em cargas de trabalho Rails:
Class#newestá mais rápido em todos os casos, especialmente com keyword arguments, e o ganho já vem integrado ao YJIT e ao ZJIT.- Os heaps do GC para diferentes size pools agora crescem de forma independente, reduzindo o uso de memória, e o sweeping está mais rápido em páginas de objetos grandes.
- O acesso a variáveis de instância está mais rápido para objetos "generic ivar", como
StringeArray. - O GC só passa a manter sua tabela interna
id2refquando algo realmente precisa dela, o que acelera oobject_ide o sweeping do GC.object_idehashtambém estão mais rápidos em classes e módulos. - Mais objetos internos agora são protegidos por write barrier, o que reduz o overhead do GC.
Tudo isso acontece onde as apps Rails passam o tempo: alocando objetos, lendo variáveis de instância e coletando lixo. Isso se traduz diretamente em throughput, latência e custo de infraestrutura, e você ganha tudo isso só de atualizar.
O Ractor Amadurece
O Ractor, o modelo de execução paralela do Ruby, passou por uma reformulação substancial. A nova classe Ractor::Port substitui o antigo modelo de mensagens, Ractor#join e Ractor#value espelham seus equivalentes em Thread, e Ractor.shareable_proc facilita passar procs entre Ractors. Internamente, muitas estruturas de dados foram refeitas para reduzir a contenção no lock global e nos caches da CPU. O time core diz que pretende tirar o rótulo de experimental do Ractor em 2026.
O preço é uma breaking change: Ractor.yield, Ractor#take, Ractor#close_incoming e Ractor#close_outgoing foram removidos, então código escrito com a API antiga precisa migrar para ports.
Mudanças na Linguagem e o Que Verificar Antes de Atualizar
Duas mudanças na linguagem se destacam. *nil não chama mais nil.to_a, assim como **nil já não chama nil.to_hash. E um operador lógico no início de uma linha agora continua a linha anterior, do mesmo jeito que um . no início faz em cadeias de métodos:
if user.active?
&& user.confirmed?
# O Ruby 4.0 lê isso como uma única condição
end
É na lista de compatibilidade que os upgrades realmente quebram. Antes de atualizar apps em produção, verifique:
- Saída do
Set:Setagora é uma classe do core, eSet#inspectimprimeSet[1, 2, 3]em vez de#<Set: {1, 2, 3}>. Testes de snapshot e parsers de log que dependem do formato antigo vão falhar. SortedSet: não é mais carregado via autoload. Adicione a gemsorted_sete façarequire "sorted_set"explicitamente.Net::HTTP: requisições com corpo não recebem maisContent-Type: application/x-www-form-urlencodedpor padrão. Defina o header você mesmo se algum servidor depender dele.- CGI: removido das default gems. Só resta o
cgi/escape(CGI.escape,CGI.escapeHTMLe companhia). - Backtraces: os frames
<internal:...>sumiram, e os erros de "wrong number of arguments" agora incluem o nome da classe do receptor. Testes que verificam backtraces ou mensagens exatas podem precisar de ajuste. - APIs removidas: a criação de processos via
|no início do argumento emKernel#opene nos métodos deIO, além deProcess::Status#&e#>>.ObjectSpace._id2refagora está depreciado.
Ferramentas: Bundled Gems e Bundler 4
Várias bibliotecas passaram de default gems para bundled gems, entre elas logger 1.7.0, irb 1.16.0, reline 0.6.3, rdoc 7.0.2, benchmark, ostruct e pstore. As bundled gems continuam vindo com o Ruby, mas com o Bundler elas só carregam se o seu Gemfile ou outra gem as declarar, então uma app que faz require de ostruct ou benchmark diretamente precisa adicioná-las. O Ruby 4.0 também vem com RubyGems e Bundler 4.0.3, e o time do RubyGems publicou um guia de upgrade que vale a leitura antes de atualizar.
O lançamento não se limita ao interpretador. Ele faz avançar juntos a linguagem, as ferramentas oficiais e a experiência de desenvolvimento, e é nessa combinação que desenvolvedores Ruby e Rails vão sentir o impacto real.
Por Que Isso Importa
O Ruby 4.0 transforma em recursos entregues prioridades que vinham sendo construídas no ecossistema há anos: isolamento, desempenho, maturidade em concorrência e um ambiente padrão mais limpo. Com o mercado pressionando linguagens e frameworks por eficiência e previsibilidade, o Ruby respondeu com um lançamento que combina experimentação de verdade (Box e ZJIT) com ganhos pragmáticos que você obtém no momento em que atualiza.
Fontes
- Ruby 4.0.0 Released (ruby-lang.org, 25 de dezembro de 2025)
- Ruby 4.0 NEWS (changelog completo)
- Documentação do Ruby::Box
- ZJIT is now available in Ruby 4.0 (Rails at Scale)
- Koichi Sasada sobre o
Ractor::Port - Upgrading to RubyGems/Bundler 4 (RubyGems Blog)
- Keynote de Matz na RubyWorld Conference 2025 (@IT, em japonês)
Comentários
Faça login com GitHub para comentar.
Ainda não há comentários.