IronRuby 4.0.5 : Ruby 4.0 sur .NET 10 et .NET 11
Fin septembre, j’ai écrit sur IronRuby 4.0, mon fork qui amène IronRuby à Ruby 4.0, avec prism comme parseur. À l’époque, il tournait sur .NET 8 et le premier téléchargement s’appelait 4.0.0-preview1. Six semaines et six versions plus tard, IronRuby 4.0.5 est sorti. C’est la première version qui tourne sur .NET 10 et .NET 11, et la première sans .NET 8.
$ ./ironruby -e 'puts RUBY_DESCRIPTION'
IronRuby 4.0.5 (4.0.0) on .NET 10.0.15 [x86_64-linux]
Pourquoi .NET 8 devait partir
Le support de .NET 8 par Microsoft a pris fin hier, le 10 novembre 2026. La 4.0.4 était la dernière version pour lui. À partir de la 4.0.5, IronRuby se compile pour net10.0 et net11.0, et le code dont seul .NET 8 avait besoin est supprimé.
Chaque téléchargement existe maintenant en deux versions :
- .NET 10, par défaut. Les fichiers gardent les noms des versions précédentes, comme
ironruby-4.0.5-linux-x64.tar.gz, et l’installeur Windows utilise aussi cette version. .NET 10 est une version LTS, supportée jusqu’au 14 novembre 2028. - .NET 11, avec
-net11-dans le nom, pour Linux, Windows et macOS. Il n’y a pas d’installeur pour elle.
Les deux embarquent leur propre runtime : pas besoin d’installer .NET pour lancer des scripts Ruby. Seul un programme qui intègre IronRuby, ou charge ses assemblies, a désormais besoin de .NET 10 ou plus récent.
Sur .NET 11, le démarrage est environ 5 % plus court, et la collection de benchmarks de TruffleRuby tourne environ 3,5 % plus vite. La version par défaut reste .NET 10, parce que c’est la version LTS.
Deux petites choses changent avec le runtime. Un Integer ne peut plus dépasser environ 2**31 bits, car c’est la limite du BigInteger de .NET depuis .NET 9. 1 << 2**31 lève maintenant NoMemoryError, comme CRuby quand une allocation échoue. Et sous Windows, zlib utilise maintenant le zlib-ng intégré à .NET : Zlib::ZLIB_VERSION change, et les octets compressés peuvent différer de ceux de la 4.0.4. Une fois décompressés, ils donnent le même résultat.
Ce qui s’est passé depuis septembre
La 4.0.5 elle-même est une petite version. Les grands changements sont venus dans les quatre versions précédentes. Voici ceux que je trouve les plus importants.
Rails avec SQLite, aussi sous Windows
Sam Ruby (@rubys) a fait tourner des applications Rails que son projet Roundhouse transpile, et a trouvé les premiers bugs : les pipes et les sockets sous macOS, où Puma ne démarrait pas, IO#write_nonblock, qui tronquait les grandes réponses, et un crash de SQLite sous Linux. Les trois sont corrigés depuis la 4.0.1.
Avec la 4.0.2, une application Rails 8.1 tourne avec SQLite sous Windows : gem install rails, rails new, un scaffold, des migrations, Turbo et Stimulus, et bin/rails server sur Puma. Dans un test de gems populaires sous Windows, 81 ont donné la même sortie que CRuby, octet pour octet, dont rubocop, rspec, pry et prawn. TLS fonctionne aussi, dans net/http comme dans Puma.
Un installeur Windows et irb
Depuis la 4.0.3, il y a un installeur Windows dans le style de RubyInstaller. Il installe dans C:\IronRuby40-x64, fonctionne sans droits d’administrateur et met ironruby, iirb et igem dans le PATH. irb et gem restent ceux de CRuby, les deux peuvent donc cohabiter.
irb fonctionne maintenant sous Windows comme dans CRuby, avec les couleurs, la complétion basée sur les types et les accents correctement affichés dans la console. Et l’interpréteur s’appelle maintenant ironruby, comme celui de JRuby s’appelle jruby. Lancé dans un terminal sans script, il ouvre irb.
.NET comme on écrit Ruby 4
Appeler .NET est devenu bien plus agréable. Les arguments nommés sont liés aux paramètres .NET par leur nom, et un bloc va à un paramètre de type délégué : list.Sort { |a, b| b <=> a } et Task.Run { } fonctionnent tout simplement.
Grâce à @sholden, using accepte maintenant aussi un namespace .NET, comme la directive using de C#. Ses méthodes d’extension ne valent alors que pour le reste du fichier :
using System::Linq
list = System::Collections::Generic::List[Integer].new([3, 1, 2])
p list.where { it > 1 }.order_by { -it }.to_a # => [3, 2]
Les 101 exemples LINQ tournent dans la CI.
Beaucoup plus rapide
La 4.0.4 portait surtout sur la vitesse. Une série de benchmarks avait listé les endroits où IronRuby était loin derrière CRuby, et la plupart sont maintenant comblés ou bien plus petits :
- Une exception rattrapée coûte environ un quart de ce qu’elle coûtait.
- Copier une longue String prend un temps constant :
s.dupde 100 Ko est passé de 83 à 0,3 µs. RationaletComplexsont écrits en C# :Rational(1, 3)est passé de 540 à 49 ns, plus rapide que CRuby.- lobsters de ruby-bench tourne 31 à 38 % plus vite, et le décodage de protoboeuf est passé de 81 s à 1,3 s.
- Avec un moteur de rendu Doom en Ruby, une image prend 16 à 18 ms au lieu d’environ 27 ms. CRuby sans YJIT en met 22 à 25.
Le point faible reste les exceptions : en lever une coûte quelques dizaines de microsecondes, contre 1 à 6 dans CRuby, à cause de la façon dont .NET gère les exceptions.
Plus proche de CRuby
Encore quelques points où IronRuby se comporte maintenant comme CRuby 4.0 :
- Une récursion profonde lève une
SystemStackErrorque l’on peut rattraper. Avant, elle terminait le processus. Ractorest là, avec l’API de Ruby 4.0. 146 des 153 vérifications des tests Ractor de CRuby passent.- Les messages d’erreur ressemblent à ceux de CRuby, avec error_highlight et les erreurs de syntaxe annotées de prism.
- Les messages d’erreur citent les noms
'comme ceci', comme CRuby depuis la 3.4. - Davantage de gems avec des extensions C fonctionnent, parce que leur extension est portée en C#, par exemple strptime, yajl-ruby et zstd-ruby. 34 des 36 grands benchmarks de ruby-bench tournent.
Merci
IronRuby a reçu ses premières contributions de l’extérieur. Merci à Sam Ruby pour les corrections sur macOS et les sockets, à @khasinski pour File#flock sur macOS et ir -S, et à @sholden pour les refinements, LINQ, les threads et bien plus.
L’essayer
La page de la version propose les téléchargements pour Linux x64, Windows x64 et macOS sur Apple silicon. Sous Windows, le plus simple est l’installeur, ironruby-4.0.5-win-x64-setup.exe. Ailleurs, il suffit de décompresser l’archive :
$ tar xzf ironruby-4.0.5-linux-x64.tar.gz
$ cd ironruby-4.0.5-linux-x64
$ ./ironruby
$ ./ironruby script.rb
$ ./igem.sh install rack
Chaque fichier a une attestation de provenance signée, qui permet de vérifier quel workflow l’a construit et à partir de quel commit :
$ gh attestation verify ironruby-4.0.5-linux-x64.tar.gz --repo Largo/ironruby
Les versions macOS sont construites dans la CI, mais je ne les ai encore presque pas testées. Si vous essayez IronRuby et que quelque chose ne marche pas, ouvrez une issue ou écrivez-moi.