Ruby 3.4 en 2026: YJIT mejorado, Prism parser y las novedades que importan

Ruby 3.4 llegó en diciembre de 2024 con el ciclo de navidad de siempre, y esta vez trajo cambios que llevan meses en cocción. El más llamativo es YJIT, el compilador JIT que apareció en Ruby 3.1 y que en cada versión ha ido ganando músculo. La otra gran novedad es Prism, el nuevo parser que en 3.4 pasa a ser el predeterminado. Son dos piezas distintas, pero juntas cambian bastante cómo funciona Ruby por dentro.

YJIT: de experimental a imprescindible

YJIT (Yet Another JIT) nació dentro de Shopify como respuesta al JIT que incluía Ruby 2.6, que era lento de compilar y apenas mejoraba el rendimiento en producción. La apuesta de Shopify fue diferente: un compilador lazy que solo compila los métodos más llamados, sin bloquear la ejecución mientras lo hace.

En Ruby 3.1 llegó como experimental. En Ruby 3.2 ya mejoró un 40% el rendimiento en benchmarks reales. En Ruby 3.3 se habilitó por defecto. Y en Ruby 3.4 el cambio más gordo es que YJIT funciona correctamente en entornos multihilo, algo que antes daba problemas.

Para activarlo (si por alguna razón no lo tienes activo) basta con:

# Desde la línea de comandos
ruby --yjit mi_script.rb

# O para ver las estadísticas de compilación
ruby --yjit --yjit-stats mi_script.rb

# Dentro del código, si quieres activarlo condicionalmente
RubyVM::YJIT.enable if defined?(RubyVM::YJIT)

Las ganancias reales dependen del código, pero en aplicaciones Rails con carga típica se habla de mejoras del 15-25% en tiempo de respuesta sin tocar una línea de código. Shopify reporta mejoras más altas en sus propias apps, pero ellos tienen un perfil de uso muy concreto.

Prism: el parser que Ruby necesitaba

El parser de Ruby histórico, parse.y, era un archivo de gramática de más de 14.000 líneas que pocos se atrevían a tocar. Era difícil de mantener, lento de compilar y generaba errores de sintaxis con mensajes que no ayudaban nada.

Prism empezó como proyecto de Shopify con un objetivo ambicioso: reescribir el parser desde cero, hacerlo rápido, portable y capaz de generar mensajes de error útiles. En Ruby 3.3 llegó como alternativa. En Ruby 3.4 es el parser por defecto.

El cambio más visible para los usuarios son los mensajes de error. Antes obtenías algo como SyntaxError (unexpected end, expecting ';' or 'n') sin ninguna pista de dónde estaba el problema. Ahora Prism señala exactamente la línea y el carácter:

# Código con error
def saludar(nombre
  puts "Hola, #{nombre}"
end

# Error con Prism (Ruby 3.4):
# test.rb:1:18: error: expected a `)` to close the parameters
# def saludar(nombre
#                   ^

Para herramientas como RuboCop, Solargraph o los plugins de los editores, Prism también es una mejora enorme porque ofrece una API pública estable para recorrer el AST. Antes cada herramienta tenía su propia forma de parsear Ruby.

El bloque implícito con "it"

Ruby 3.4 añadió it como alias del parámetro de bloque implícito. Antes ya existía _1, _2, etc., pero it es más legible en bloques de un solo argumento:

# Con _1 (disponible desde Ruby 2.7)
[1, 2, 3].map { _1 * 2 }
# => [2, 4, 6]

# Con it (nuevo en Ruby 3.4)
[1, 2, 3].map { it * 2 }
# => [2, 4, 6]

# Más útil en cadenas de métodos
usuarios.select { it.activo? }.map { it.nombre }

Es un cambio pequeño, pero encaja con el estilo de Ruby de hacer el código lo más legible posible sin sacrificar expresividad.

Otras mejoras de Ruby 3.4

Hay más novedades que merecen mención:

  • Mejoras en Fiber: los Fiber scheduler de Ruby 3.1 ganan nuevos hooks para operaciones de red y filesystem, lo que beneficia a librerías como Async y Falcon.
  • GC mejorado: el recolector de basura tiene mejor comportamiento en aplicaciones con muchos objetos de corta vida, que es exactamente el patrón de Rails.
  • Hash#except siempre disponible: ya estaba desde Ruby 3.0, pero en 3.4 se añaden métodos adicionales de Array y Enumerable que reducen la necesidad de librerías externas para operaciones comunes.
  • Frozen string literals: sigue el avance hacia hacer strings inmutables por defecto en Ruby 4, aunque todavía no llega en 3.4.

Compatibilidad y migración

Si tienes un proyecto en Ruby 3.2 o 3.3, la migración a 3.4 debería ser sencilla. Los breaking changes son mínimos y bien documentados. Lo que sí conviene revisar:

  • Si usas it como nombre de variable en bloques, Ruby 3.4 avisa con un warning en 3.3 y rompe en 3.4. Renómbralo.
  • Algunas gemas que parseaban código Ruby directamente pueden necesitar actualización si usaban el parser antiguo vía C extensions.
  • YJIT requiere que Ruby esté compilado con soporte Rust (desde Ruby 3.2 ya viene así en los paquetes oficiales). Si compilas desde fuente necesitas Rust 1.58+.

Si trabajas con Ruby en el contexto de APIs o scripting, también puede interesarte ver cómo FastAPI resuelve el rendimiento en Python, otro lenguaje dinámico con sus propias apuestas de compilación JIT.

El ritmo de releases de Ruby

Ruby lleva desde 2013 publicando una versión mayor cada 25 de diciembre, con versiones de parche durante el año. Es un ciclo predecible que facilita la planificación. Ruby 3.5 llegará en diciembre de 2025 y se espera que continúe el trabajo en YJIT para aplicaciones con muchos hilos y más mejoras en el GC.

Lo que ha cambiado en los últimos años es que el núcleo del proyecto recibe más contribuciones de empresas (Shopify, GitHub, Oracle) que antes dependían de voluntarios individuales. Eso ha acelerado mejoras como YJIT o Prism que requieren un esfuerzo sostenido durante varios años.

Ruby 3.4 no es una revolución, pero sí consolida el trabajo de los últimos tres años. Si llevas tiempo dudando si actualizar desde Ruby 3.1 o 3.2, ahora tienes buenos motivos para hacerlo.

Imagen: Pexels / Digital Buggu

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP