Ruby 4.0.0
(ruby-lang.org)- Ruby 4.0.0 a été publié, introduisant Ruby Box et ZJIT, ainsi que de nombreuses améliorations de performances et du langage
- Ruby Box est une fonctionnalité expérimentale permettant d’exécuter en isolation des classes, modules, variables globales et définitions de bibliothèques natives/Ruby
- ZJIT est un compilateur JIT nouvelle génération basé sur Rust, structurellement plus extensible que YJIT et facilitant les contributions externes
- Le modèle d’exécution parallèle Ractor a été amélioré en termes de stabilité et de performances, avec une sortie prévue de son statut expérimental
- Des mises à jour touchant les classes cœur, la bibliothèque standard, l’API C, le GC et le JIT renforcent les performances et l’extensibilité de l’écosystème Ruby
Présentation de Ruby 4.0
- Ruby 4.0.0 est une mise à jour majeure centrée sur Ruby Box et ZJIT
- Elle inclut des améliorations dans de nombreux domaines : exécution parallèle, syntaxe du langage, bibliothèque standard, GC, JIT, etc.
- Le téléchargement est proposé aux formats
.tar.gz,.tar.xzet.zip
Ruby Box
- Ruby Box est une fonctionnalité expérimentale qui fournit l’isolation des définitions
- Elle s’active en définissant la variable d’environnement
RUBY_BOX=1, et la classe estRuby::Box - Les définitions chargées à l’intérieur d’une box sont isolées de l’extérieur : les monkey patches, variables globales/de classe, définitions de classes/modules et modifications de bibliothèques n’affectent pas les autres box
- Elle s’active en définissant la variable d’environnement
- Principaux cas d’usage
- Exécution isolée entre cas de test
- Exécution parallèle de web apps pour un déploiement blue-green
- Exécution parallèle pour valider des mises à jour de dépendances
- Utilisation prévue comme API de base pour implémenter à l’avenir une « package API » de haut niveau
ZJIT
- ZJIT est un nouveau compilateur JIT développé comme version nouvelle génération de YJIT
- Nécessite Rust 1.85.0 ou supérieur, s’active avec l’option
--zjit - Repose sur SSA IR, prend en charge des unités de compilation plus larges et adopte une structure favorisant les contributions externes
- Nécessite Rust 1.85.0 ou supérieur, s’active avec l’option
- Il est actuellement plus rapide que l’interpréteur, mais plus lent que YJIT
- Son utilisation en production n’est pas recommandée, et des gains de performance sont prévus pour Ruby 4.1
Améliorations de Ractor
- Ajout de la classe Ractor::Port pour résoudre les problèmes d’envoi/réception de messages
Ractor.shareable_procfacilite le partage d’objets Proc entre Ractors- L’amélioration des structures de données internes réduit la contention sur le verrou global et améliore le parallélisme
- Le statut expérimental de Ractor devrait être levé l’année prochaine
Changements du langage
*niln’appelle plusnil.to_a(même comportement que**nil)- Les opérateurs logiques (
||,&&,and,or) prennent en charge la syntaxe de continuité de ligne (dot chaining) - Amélioration de la lisibilité et de la cohérence du code
Mises à jour des classes cœur
- Array : ajout de
Array#rfindetArray#findpour une recherche plus efficace - Binding : exclusion des paramètres numérotés et ajout de méthodes liées à
implicit_parameters - Enumerator : ajout de l’argument nommé
size:àproduce - ErrorHighlight : affichage d’extraits de code de l’appelant et de la définition lors d’un
ArgumentError - Fiber/Fiber::Scheduler : ajout de
raise(cause:),fiber_interrupt,yield, etc. - File : prise en charge de
File::Stat#birthtimesous Linux - IO : timeout
Float::INFINITYautorisé, suppression de la création de processus basée sur les pipes - Kernel : personnalisation possible de
#inspect, suppression de la création de pipes dansKernel#open - Math : ajout de
log1petexpm1 - Pathname : promotion de gem par défaut à classe cœur
- Proc : unification du format d’affichage des paramètres anonymes
- Ractor : communication remaniée autour de
Ractor::Port, suppression deRactor.yield, etc. - Set : promotion en classe cœur, simplification du format de
inspect - Socket : ajout de l’argument
open_timeout, unification des exceptions de timeout - String : prise en charge d’Unicode 17.0.0 et Emoji 17.0, extension des méthodes de la famille
strip - Thread : prise en charge de l’argument
raise(cause:)
Mises à jour de la bibliothèque standard (Stdlib)
- Promues en gems par défaut :
ostruct,pstore,benchmark,logger,rdoc,win32ole,irb,reline,fiddle, etc. - Nouvelle gem par défaut :
win32-registry 0.1.2 - Mise à jour des gems par défaut :
RubyGems 4.0.3,bundler 4.0.3,openssl 4.0.0,json 2.18.0, etc. - Mise à jour des gems bundle :
minitest 6.0.0,rake 13.3.1,rbs 3.10.0,debug 1.11.1, etc. - Intègre RubyGems/Bundler 4
Prise en charge des plateformes
- Windows : fin de la prise en charge des versions antérieures à MSVC 14.0 (Visual Studio 2015 ou plus requis)
Changements de compatibilité
- Suppression de
Ractor.yield,Ractor#take,Ractor#close_incoming,Ractor#close_outgoing - Dépréciation de
ObjectSpace._id2ref - Suppression de
Process::Status#&et#>> - Simplification de l’affichage des frames internes dans les backtraces
- Les backtraces de
ArgumentErroraffichent désormais le nom de la classe/du module receveur
Compatibilité de la bibliothèque standard
- Suppression de la bibliothèque CGI, seul
cgi/escapeest conservé - Avec la promotion de
Seten classe cœur,SortedSetnécessite désormais l’installation d’une gem séparée - Suppression du réglage automatique de l’en-tête
Content-TypedansNet::HTTP
Mises à jour de l’API C
- Désactivation de
rb_thread_fd_closeet recommandation d’utiliserrb_io_close rb_thread_call_with_gvlfonctionne désormais indépendamment de la présence du GVL- Ajout d’une API C pour Set (
rb_set_new,rb_set_add,rb_set_delete, etc.)
Améliorations d’implémentation et de performances
- Accélération des appels à
Class#new, notamment avec des arguments nommés - Réduction de l’usage mémoire grâce à la croissance indépendante des pools du tas GC
- Amélioration de la vitesse de sweeping des objets volumineux
- Optimisations de
object_id, du calcul dehashet de l’accès aux variables d’instance - Améliorations des performances de Ractor
- Structure de hash sans verrou, réduction de la contention du cache, optimisation des allocations d’objets
- Corrections de bugs liés aux deadlocks, à l’encodage et au GC
À propos du JIT
- ZJIT : JIT basé sur les méthodes, nécessite Rust 1.85.0 ou supérieur, activable via
--zjitouRubyVM::ZJIT.enable - YJIT : changement des options de statistiques, ajout de
mem_size:etcall_threshold: - RJIT : suppression de
--rjit, déplacement vers un dépôt séparé
Ampleur des changements
- Par rapport à Ruby 3.4.0 : 3 889 fichiers modifiés, 230 769 lignes ajoutées, 297 003 lignes supprimées
- Ruby 4.0 est une version majeure qui renforce fortement les performances, le parallélisme et la cohérence du langage
Téléchargement
- Disponible aux formats
ruby-4.0.0.tar.gz,ruby-4.0.0.tar.xz,ruby-4.0.0.zip - Les hashs SHA1, SHA256 et SHA512 de chaque fichier sont indiqués
Présentation de Ruby
- Ruby est un langage open source créé en 1993 par Yukihiro Matsumoto (Matz)
- Il fonctionne sur de multiples plateformes et est particulièrement utilisé dans le développement web à l’échelle mondiale
1 commentaires
Réactions sur Hacker News
Joyeux anniversaire à Ruby !
On entend souvent que « les gens sont partis parce que Ruby n’avait pas de typage », mais aujourd’hui RBS est en train de s’imposer comme standard. Sorbet le prend aussi en charge, et une notation inline permettant d’écrire les types directement à côté du code est apparue.
Et le discours selon lequel « Ruby a un LSP faible » n’est plus vraiment d’actualité non plus. ruby-lsp est devenu la référence, et il prend aussi en charge le « go to definition ». Grâce à son architecture de plugins, plusieurs outils peuvent réutiliser le même AST.
La parallélisation s’est aussi beaucoup améliorée grâce à Ractor, et avec encore un peu de travail sur le GC, cela semble proche de sortir complètement de la phase expérimentale.
Il y a aussi de nouvelles fonctionnalités comme ZJIT ou Box, mais elles ne sont pas encore recommandées en production. Cela dit, ça progresse constamment.
Je trouve aussi positif que la syntaxe ne change pas brutalement
À Noël, il faut toujours une nouvelle version de Ruby.
Cette fois, ruby::box est intéressant. Il permet de faire tourner en parallèle deux versions d’un déploiement de fonctionnalité.
Et le fait de pouvoir écrire
if condition1 && condition2sur plusieurs lignes est aussi plutôt sympaif condition1 && condition2sur plusieurs lignes depuis longtemps, et ça fonctionnait très bien. Je ne vois pas bien en quoi la nouvelle syntaxe est différenteJe suis content de voir Ruby 4.0 sortir, mais en 2025 je suis passé complètement à Python.
Claude Code a converti automatiquement mes projets Ruby en Python à 100 %, et depuis je n’ai plus de raison d’utiliser Ruby.
J’ai adoré Ruby pendant plus de dix ans et j’ai même écrit des livres dessus, mais aujourd’hui fastapi, pytorch, langchain et streamlit font gagner Python grâce à son écosystème. Cela dit, je trouve toujours que la syntaxe de Ruby reste la plus élégante
À Noël, on ne peut décidément pas se passer d’une nouvelle version de Ruby. Merci à Matz et à l’équipe
Auriez-vous des ressources récentes à recommander à quelqu’un qui veut apprendre Ruby en 2025~26 ? Je me demande s’il existe de bons livres en dehors de la documentation officielle
Cours Ruby on Rails de Pragmatic Studio
Ruby est vraiment un langage incroyable. Récemment, j’ai créé une couche au-dessus de Rails qui génère une API à partir d’un simple fichier Markdown, et faire la même chose en Python aurait été bien plus compliqué. En JavaScript, cela aurait été encore pire. La capacité de métaprogrammation de Ruby est vraiment à part
Je suis content que les stack traces internes aient été nettoyées. J’aimerais qu’un jour les chemins relatifs soient aussi pris en charge. Et c’est bien aussi que Set soit enfin traité comme il le mérite
Je travaille aujourd’hui dans une entreprise qui n’utilise pas Ruby, mais j’ai toujours une profonde affection pour ce langage. Merci pour cette release, et j’espère avoir à nouveau l’occasion de m’en servir
J’avais entendu dire autrefois que la fonctionnalité Ruby::Box (namespace) provoquait une grave dégradation des performances ; je me demande si cela a été amélioré cette fois-ci
J’aimerais savoir si le tooling s’est amélioré. Je n’ai encore jamais réussi à faire tourner correctement un LSP sur Windows