6 points par GN⁺ 2025-12-26 | 1 commentaires | Partager sur WhatsApp
  • 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.xz et .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 est Ruby::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
  • 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
  • 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_proc facilite 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

  • *nil n’appelle plus nil.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#rfind et Array#find pour 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#birthtime sous Linux
  • IO : timeout Float::INFINITY autorisé, suppression de la création de processus basée sur les pipes
  • Kernel : personnalisation possible de #inspect, suppression de la création de pipes dans Kernel#open
  • Math : ajout de log1p et expm1
  • 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 de Ractor.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 ArgumentError affichent désormais le nom de la classe/du module receveur

Compatibilité de la bibliothèque standard

  • Suppression de la bibliothèque CGI, seul cgi/escape est conservé
  • Avec la promotion de Set en classe cœur, SortedSet nécessite désormais l’installation d’une gem séparée
  • Suppression du réglage automatique de l’en-tête Content-Type dans Net::HTTP

Mises à jour de l’API C

  • Désactivation de rb_thread_fd_close et recommandation d’utiliser rb_io_close
  • rb_thread_call_with_gvl fonctionne 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 de hash et 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 --zjit ou RubyVM::ZJIT.enable
  • YJIT : changement des options de statistiques, ajout de mem_size: et call_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

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

    • Je suis un rubyste hardcore, et ruby-lsp est vraiment excellent. En revanche, je ne dirais pas que RBS est en train de devenir un standard. En pratique, son taux d’adoption reste très faible. rbs-inline relève plutôt du projet personnel et l’activité y est limitée. Cela dit, je trouve encourageant que son développeur essaie de l’intégrer directement à RBS. Personnellement, je doute qu’un système de types basé sur des annotations se diffuse largement
    • Ruby est tout simplement inférieur à Python. Il existe un système presque identique, plus rapide et avec une communauté plus grande, donc il n’y a aucune vraie raison d’utiliser Ruby
  • À 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 && condition2 sur plusieurs lignes est aussi plutôt sympa

    • Un jour, j’aimerais que chaque Ractor s’exécute dans sa propre ruby::box, et que chaque box puisse lancer son propre GC de manière indépendante. On pourrait alors avoir un vrai parallélisme d’exécution, un peu comme BEAM. La latence p99 baisserait aussi. Bien sûr, le partage d’objets introduirait un coût de copie, mais dans la plupart des applications il serait probablement négligeable
    • J’écris déjà if condition1 && condition2 sur plusieurs lignes depuis longtemps, et ça fonctionnait très bien. Je ne vois pas bien en quoi la nouvelle syntaxe est différente
  • Je 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

    • Tout ce que tu cites, ce sont des bibliothèques de l’écosystème Python, pas des avantages du langage lui-même. Beaucoup de développeurs migrent vers Python pour ses bibliothèques plus que pour le langage. Résultat, Python est tiré dans de multiples directions et rencontre de plus en plus un problème de dilution de sa philosophie de langage. Ruby, au contraire, rassemble des gens qui aiment le langage lui-même, et il préserve donc mieux son essence
    • Moi aussi, cette année, je suis passé de Ruby à Kotlin. L’absence de typage statique me mettait trop mal à l’aise. Kotlin offre de bonnes performances, et le fait qu’il consomme un peu plus de mémoire n’est plus vraiment un problème aujourd’hui. J’aime toujours Ruby, mais je ne l’utilise plus que pour de petits scripts
    • Le support IDE est bien meilleur en Python, et rien que pour ça, le changement valait le coup. La dynamique excessive de Ruby n’est pas à mon goût
    • J’ai essayé d’utiliser Langchain, mais ça évolue tellement vite que la documentation n’arrive pas du tout à suivre. Quand on cherche, on tombe surtout sur des articles du genre « pourquoi la documentation de Langchain est-elle si mauvaise ? ». Je suis donc passé à Haystack, et j’en suis beaucoup plus satisfait
    • J’aime aussi pandas, numpy et pytorch, mais je prends toujours beaucoup de plaisir à créer des applications web full-stack avec Rails. C’est pour ça que j’adore vraiment pyCall
  • À 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

    • J’ai suivi les cours Elixir et Erlang de Pragmatic Studio, et la qualité était vraiment très élevée. Ils proposent aussi des cours sur Ruby et Rails
      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

    • Intéressant, tu pourrais montrer un exemple ?
  • 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

    • Ce serait vraiment bien d’avoir des chemins relatifs dans les stack traces
  • 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

    • À mon avis, programmer sur Windows, c’est se faire souffrir volontairement. En dehors des langages Microsoft, Linux ou macOS sont bien meilleurs
    • L’expérience développeur (DX) de Ruby est en dessous des attentes, et c’est encore pire sur Windows. Heureusement, des présentations ont reconnu ce problème et cherché à l’améliorer
    • Tu as essayé WSL2 ?