- Se lanzó Ruby 4.0.0, que introduce el nuevo Ruby Box y ZJIT, e incluye numerosas mejoras de rendimiento y del lenguaje
- Ruby Box es una función experimental que permite la ejecución aislada de clases, módulos, variables globales y definiciones de bibliotecas nativas/Ruby
- ZJIT es un compilador JIT de próxima generación basado en Rust; su estructura es más escalable que la de YJIT y facilita las contribuciones externas
- El modelo de ejecución paralela Ractor fue mejorado en estabilidad y rendimiento, y se planea quitar su estado experimental en el futuro
- Las actualizaciones en clases principales, biblioteca estándar, API de C, GC y JIT fortalecen el rendimiento y la escalabilidad del ecosistema Ruby
Resumen de Ruby 4.0
- Ruby 4.0.0 es una gran actualización centrada en Ruby Box y ZJIT
- Incluye mejoras en múltiples áreas como ejecución paralela, sintaxis del lenguaje, biblioteca estándar, GC y JIT
- La descarga se ofrece en formatos
.tar.gz, .tar.xz y .zip
Ruby Box
- Ruby Box es una función experimental que proporciona aislamiento de definiciones
- Se activa al configurar la variable de entorno
RUBY_BOX=1, y la clase es Ruby::Box
- Las definiciones cargadas dentro de una box quedan aisladas del exterior, por lo que los monkey patches, las variables globales/de clase, las definiciones de clases/módulos y los cambios en bibliotecas no afectan a otras boxes
- Casos de uso principales
- Ejecución aislada entre casos de prueba
- Ejecución paralela de aplicaciones web para despliegues blue-green
- Ejecución paralela para validar actualizaciones de dependencias
- En el futuro servirá como API base para implementar una “API de paquetes” de alto nivel
ZJIT
- ZJIT es un nuevo compilador JIT desarrollado como la siguiente generación de YJIT
- Requiere Rust 1.85.0 o superior y se activa con la opción
--zjit
- Soporta unidades de compilación más grandes basadas en SSA IR y tiene una estructura que fomenta las contribuciones externas
- Actualmente es más rápido que el intérprete, pero más lento que YJIT
- No se recomienda su uso en producción, y se prevén mejoras de rendimiento en Ruby 4.1
Mejoras en Ractor
- Se agregó la clase Ractor::Port para resolver problemas de envío y recepción de mensajes
Ractor.shareable_proc facilita compartir objetos Proc entre Ractors
- Las mejoras en las estructuras de datos internas reducen la contención del lock global y aumentan el paralelismo
- Está previsto quitar el estado experimental de Ractor el próximo año
Cambios en el lenguaje
*nil ya no llama a nil.to_a (mismo comportamiento que **nil)
- Los operadores lógicos (
||, &&, and, or) ahora soportan la sintaxis de continuación de línea (dot chaining)
- Mejora la legibilidad y la consistencia del código
Actualizaciones en clases principales
- Array: se agregan
Array#rfind y Array#find para búsquedas más eficientes
- Binding: exclusión de parámetros numerados y nuevos métodos relacionados con
implicit_parameters
- Enumerator: se agrega el argumento con palabra clave
size: a produce
- ErrorHighlight: al producirse
ArgumentError, muestra fragmentos de código del llamador y de la definición
- Fiber/Fiber::Scheduler: se agregan
raise(cause:), fiber_interrupt, yield y más
- File: soporte para
File::Stat#birthtime en Linux
- IO: se permiten timeouts con
Float::INFINITY y se elimina la creación de procesos basada en pipes
- Kernel: se puede personalizar
#inspect, y se elimina la creación de pipes en Kernel#open
- Math: se agregan
log1p y expm1
- Pathname: asciende de gema por defecto a clase del núcleo
- Proc: se unifica el formato de salida de parámetros anónimos
- Ractor: cambia a una estructura de comunicación basada en
Ractor::Port, y se eliminan Ractor.yield y otros
- Set: asciende a clase del núcleo y se simplifica el formato de
inspect
- Socket: se agrega el argumento
open_timeout y se unifican las excepciones por timeout
- String: soporte para Unicode 17.0.0 y Emoji 17.0, además de ampliar los métodos de la familia
strip
- Thread: soporte para el argumento
raise(cause:)
Actualizaciones de la biblioteca estándar (Stdlib)
- Promovidas a gemas por defecto:
ostruct, pstore, benchmark, logger, rdoc, win32ole, irb, reline, fiddle y otras
- Nueva gema por defecto:
win32-registry 0.1.2
- Actualizaciones de gemas por defecto:
RubyGems 4.0.3, bundler 4.0.3, openssl 4.0.0, json 2.18.0 y otras
- Actualizaciones de gemas empaquetadas:
minitest 6.0.0, rake 13.3.1, rbs 3.10.0, debug 1.11.1 y otras
- Incluye RubyGems/Bundler 4
Soporte de plataforma
- Windows: se deja de dar soporte a versiones anteriores a MSVC 14.0 (se requiere Visual Studio 2015 o superior)
Cambios de compatibilidad
- Se eliminan
Ractor.yield, Ractor#take, Ractor#close_incoming, Ractor#close_outgoing
ObjectSpace._id2ref queda obsoleto
- Se eliminan
Process::Status#& y #>>
- Se simplifica la salida de frames internos (
backtrace)
- En el backtrace de
ArgumentError se muestra el nombre de la clase/módulo receptor
Compatibilidad de la biblioteca estándar
- Se elimina la biblioteca CGI, manteniéndose solo
cgi/escape
- Con la promoción de
Set al núcleo, SortedSet requiere instalar una gema aparte
- Se elimina la configuración automática del encabezado
Content-Type en Net::HTTP
Actualizaciones de la API de C
- Se desactiva
rb_thread_fd_close y se recomienda usar rb_io_close
rb_thread_call_with_gvl funciona independientemente de si hay GVL o no
- Se agrega una API de C para Set (
rb_set_new, rb_set_add, rb_set_delete, etc.)
Mejoras de implementación y rendimiento
- Se acelera la llamada a
Class#new, especialmente al usar argumentos con palabra clave
- El crecimiento independiente de los pools del heap del GC reduce el uso de memoria
- Mejora la velocidad de barrido de objetos grandes
- Se optimizan
object_id, el cálculo de hash y el acceso a variables de instancia
- Mejoras de rendimiento en Ractor
- Estructura hash sin locks, menor contención de caché y optimización de asignación de objetos
- Corrección de bugs relacionados con deadlocks, codificación y GC
Relacionado con JIT
- ZJIT: JIT basado en métodos, requiere Rust 1.85.0 o superior, se activa con
--zjit o RubyVM::ZJIT.enable
- YJIT: cambios en las opciones de estadísticas, además de
mem_size: y call_threshold:
- RJIT: se elimina
--rjit y se traslada a un repositorio separado
Escala de los cambios
- Frente a Ruby 3.4.0, hubo 3,889 archivos modificados, 230,769 líneas añadidas y 297,003 líneas eliminadas
- Ruby 4.0 es una versión mayor que refuerza ampliamente el rendimiento, el paralelismo y la consistencia del lenguaje
Descarga
- Disponible en formatos
ruby-4.0.0.tar.gz, ruby-4.0.0.tar.xz y ruby-4.0.0.zip
- Se especifican los hashes SHA1, SHA256 y SHA512 de cada archivo
Acerca de Ruby
- Ruby es un lenguaje open source desarrollado en 1993 por Yukihiro Matsumoto (Matz)
- Se ejecuta en múltiples plataformas y es usado en todo el mundo, especialmente en el desarrollo web
1 comentarios
Opiniones en Hacker News
¡Feliz cumpleaños, Ruby!
La gente suele decir que “se fue de Ruby porque no tenía tipado”, pero ahora RBS se está consolidando como estándar. Sorbet también lo soporta, y aparecieron notaciones inline para escribir tipos justo al lado del código.
Y eso de que “Ruby tiene un LSP débil” ya quedó atrás. ruby-lsp se volvió el estándar y también soporta “go to definition”. Gracias a su arquitectura de plugins, varias herramientas pueden reutilizar el mismo AST.
La concurrencia también mejoró mucho gracias a Ractor, y si ahora pulen un poco más el GC, parece que por fin saldrá por completo de la etapa experimental.
También hay funciones nuevas como ZJIT o Box, pero todavía no se recomiendan en producción. Aun así, todo va mejorando poco a poco.
También me parece bueno que la sintaxis no cambie drásticamente
En Navidad siempre tiene que salir una nueva versión de Ruby.
Esta vez ruby::box me parece interesante. Permite ejecutar el rollout de funciones en dos versiones al mismo tiempo.
Y también está bastante genial que ahora se pueda escribir
if condition1 && condition2en varias líneasif condition1 && condition2en varias líneas desde hace tiempo y funcionaba bien. No sé qué tiene de distinto esta nueva sintaxisMe alegra ver el lanzamiento de Ruby 4.0, pero en 2025 me cambié por completo a Python.
Claude Code convirtió automáticamente mis proyectos en Ruby a Python al 100%, y desde entonces desapareció cualquier razón para seguir usando Ruby.
Amé Ruby por más de 10 años e incluso escribí libros sobre él, pero ahora fastapi, pytorch, langchain y streamlit hicieron que Python ganara gracias a su ecosistema. Aun así, sigo pensando que la sintaxis de Ruby es la más hermosa
En Navidad no puede faltar una nueva versión de Ruby. Gracias a Matz y al equipo
¿Habrá materiales recientes que valga la pena recomendarle a alguien que quiera aprender Ruby en 2025~26? Además de la documentación oficial, me da curiosidad si hay algún buen libro
Curso de Ruby on Rails de Pragmatic Studio
Ruby es de verdad un lenguaje increíble. Hace poco hice una capa sobre Rails que genera una API a partir de un solo archivo Markdown, y en Python hacer lo mismo habría sido mucho más complicado. En JavaScript habría sido todavía peor. La capacidad de metaprogramación de Ruby es realmente única
Me alegra que hayan limpiado el stack trace interno. Ojalá algún día también soporte rutas relativas. Y también está bueno que por fin Set reciba el trato que merece
Ahora trabajo en una empresa que ya no usa Ruby, pero sigo amándolo profundamente. Gracias por este lanzamiento, y ojalá vuelva a tener oportunidad de usarlo
Antes escuché que la función Ruby::Box (namespace) provocaba una degradación de rendimiento seria; me pregunto si esta vez lo mejoraron
Quisiera saber si mejoró el tooling. Todavía no he logrado correr bien LSP en Windows