Skip to content
Ruby 4.0 é lançado com Ruby Box, ZJIT e avanços de performance

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.

Publicado em 7 min de leitura

Também disponível em English

Compartilhar

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#new está 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 String e Array.
  • O GC só passa a manter sua tabela interna id2ref quando algo realmente precisa dela, o que acelera o object_id e o sweeping do GC. object_id e hash també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: Set agora é uma classe do core, e Set#inspect imprime Set[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 gem sorted_set e faça require "sorted_set" explicitamente.
  • Net::HTTP: requisições com corpo não recebem mais Content-Type: application/x-www-form-urlencoded por 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.escapeHTML e 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 em Kernel#open e nos métodos de IO, além de Process::Status#& e #>>. ObjectSpace._id2ref agora 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

Comentários

Faça login com GitHub para comentar.

Ainda não há comentários.