6 puntos por GN⁺ 2025-12-26 | 1 comentarios | Compartir por WhatsApp
  • 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

 
GN⁺ 2025-12-26
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

    • Soy bastante rubyista hardcore y ruby-lsp es realmente excelente. Pero no diría que RBS se esté convirtiendo en estándar. En la práctica, su adopción sigue siendo muy baja. rbs-inline está al nivel de un proyecto personal y tiene poca actividad. Aun así, me alegra que su desarrollador esté intentando integrarlo directamente en RBS. Personalmente, no creo que un sistema de tipos basado en comentarios se vaya a masificar
    • Ruby es simplemente inferior a Python. Existe un sistema casi igual que es más rápido y tiene una comunidad más grande, así que no hay motivo para usar Ruby
  • 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 && condition2 en varias líneas

    • Algún día estaría bueno que cada Ractor se ejecutara en su propio ruby::box, y que cada box pudiera correr su propio GC de forma independiente. Entonces sí sería posible una ejecución realmente paralela, como en BEAM. También bajaría la latencia p99. Claro, compartir objetos implicaría un costo de copia, pero en la mayoría de las apps sería mínimo
    • Yo ya venía escribiendo if condition1 && condition2 en varias líneas desde hace tiempo y funcionaba bien. No sé qué tiene de distinto esta nueva sintaxis
  • Me 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

    • Todo lo que mencionaste son bibliotecas del ecosistema de Python, no ventajas del lenguaje en sí. Mucha gente se está pasando a Python más por las librerías que por el lenguaje. Como resultado, Python está siendo jalado en muchas direcciones y tiene cada vez más el problema de que su filosofía de lenguaje se diluye. En cambio, Ruby reúne a gente a la que realmente le gusta el lenguaje en sí, así que conserva bien su esencia
    • Yo también este año me cambié de Ruby a Kotlin. La falta de tipado estático me generaba demasiada inseguridad. Kotlin rinde bien, y usar un poco más de memoria ya no es un gran problema. Ruby todavía me gusta, pero ahora solo lo uso para scripts sencillos
    • Python tiene un soporte de IDE mucho mejor, y solo por eso ya valió la pena cambiarme. La excesiva dinamicidad de Ruby no es de mi gusto
    • Intenté usar Langchain, pero cambia tan rápido que la documentación no lo sigue para nada. Si buscas, solo encuentras montones de posts del tipo “por qué la documentación de Langchain es un desastre”. Por eso me pasé a Haystack y estoy mucho más satisfecho
    • A mí también me gustan pandas, numpy y pytorch, pero sigo disfrutando hacer apps web full-stack con Rails. Por eso realmente amo pyCall
  • 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

  • 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

    • Suena interesante, ¿podrías mostrar algún ejemplo?
  • 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

    • Estaría muy bueno que el stack trace mostrara rutas relativas
  • 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

    • En mi opinión, programar en Windows es buscarse el sufrimiento. Si no estás usando un lenguaje de Microsoft, Linux o macOS son mucho mejores
    • La experiencia de desarrollador (DX) de Ruby está por debajo de lo esperado, y en Windows es todavía peor. Por suerte hubo anuncios reconociendo este problema e intentando mejorarlo
    • ¿Ya probaste WSL2?