URL: https://linuxfr.org/news/sortie-de-ruby-3-0 Title: Sortie de Ruby 3.0 Authors: contra-sh Ysabeau đŸ§¶, Quidam, miko, palm123, gUI, BenoĂźt Sibaud et Yves Bourguignon Date: 2021ćčŽ08月21æ—„T16:12:24+02:00 License: CC By-SA Tags: ruby et sortie_version Score: 46 Le 25 dĂ©cembre 2020 le langage Ruby est passĂ© en version 3.0 ! ![three](https://i.ibb.co/N9dYKmy/3.jpg) _Image de [Jack Hunter](https://unsplash.com/@jacktthunter)._ Cette version est le fruit de cinq ans de travail, le travail sur la branche 3.0 ayant commencĂ© en 2015. La suite de cette dĂ©pĂȘche retrace les changements contenus dans cette nouvelle version. ---- [Site officiel de Ruby](https://www.ruby-lang.org/en/) [Annonce officielle de la sortie de Ruby 3](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/) [Installer Ruby](https://www.ruby-lang.org/fr/downloads/) ---- # Versions La date du 25 dĂ©cembre n’est pas un hasard puisque cela fait plusieurs annĂ©es que les versions mineures sortent le 25 dĂ©cembre. Petit rappel des sorties de Ruby : - Ruby 1.0 est sorti le 25 dĂ©cembre 1996 - Ruby 2.0 le 24 fĂ©vrier 2013 - Ruby 2.1 le 25 dĂ©cembre 2013 - Ruby 2.2 le 25 dĂ©cembre 2014 - Ruby 2.5 le 25 dĂ©cembre 2015 - Ruby 2.4 le 25 dĂ©cembre 2016 - Ruby 2.5 le 25 dĂ©cembre 2017 - Ruby 2.6 le 25 dĂ©cembre 2018 - Ruby 2.7 le 25 dĂ©cembre 2019 La liste quasi complĂšte des versions de Ruby peut se trouver [ici](https://www.ruby-lang.org/en/downloads/releases/). # Liens vers d’anciennes dĂ©pĂȘches LinuxFr.org Quelques liens vers des dĂ©pĂȘches LinuxFr.org autour de Ruby et son Ă©cosystĂšme : - [Ruby 2.0 est sorti](https://linuxfr.org/news/ruby-2-0-est-sorti) (2013) - [JRuby 1.7.0](https://linuxfr.org/news/jruby-1-7-0) (2012) - [Rubinius](https://linuxfr.org/news/rubinius-10-est-sorti) (2010) # Performances Une des principales amĂ©liorations de Ruby 3.0.0 concerne les performances. En effet, Ruby peut parfois exĂ©cuter votre code jusqu’à trois fois plus vite. Ci-dessous les rĂ©sultats d’un benchmark tirĂ© de l'[annonce officielle](https://www.ruby-lang.org/en/news/2020/12/25/ruby-3-0-0-released/) : ![RĂ©sultats benchmark performances](https://i.ibb.co/C5Y4SmP/ruby3x3.png) L’accĂ©lĂ©ration provient principalement de l’utilisation du [JIT](https://fr.wikipedia.org/wiki/Compilation_%C3%A0_la_vol%C3%A9e) soit « Just-In-Time » compilation. Rappel, pour celles et ceux qui ne connaissent pas ce procĂ©dĂ© : un interprĂ©teur produit gĂ©nĂ©ralement du « byte code » (sorte de code simplifiĂ© de plus haut niveau que l’assembleur mais en restant bas niveau, parfois au format binaire). Ce byte code est ensuite exĂ©cutĂ© par une « machine virtuelle ». Dans certains cas la frontiĂšre entre interprĂ©teur et machine virtuelle est trĂšs mince (Perl, Python avec CPython, Ruby avec CRuby < 1.9) ou plus marquĂ©e (Raku = Rakudo + MoarVM/JVM/JS, Ruby = Ruby + YARV, Erlang = Erlang + BEAM) mĂȘme si cela ne change pas grand-chose d’un point de vue utilisateur (le code source semble exĂ©cutĂ© par une seule et mĂȘme entitĂ©). Le processus de gĂ©nĂ©ration de bytecode peut se faire parfois ligne par ligne (interprĂ©teur de Basic) mais peut Ă©galement ĂȘtre prĂ©cĂ©dĂ© d’une Ă©tape de gĂ©nĂ©ration de format intermĂ©diaire avec des optimisations (par exemple via un arbre de syntaxe abstraite). On nomme parfois cette Ă©tape une Ă©tape de « compilation » mais il ne s’agit pas de compilation dans le mĂȘme sens du terme que pour JIT. Le JIT consiste Ă  « compiler » certaines portions de code en code natif. Ici pour Ruby on parle de MJIT pour « Method Based JIT » c’est-Ă -dire que les boucles « chaudes » ne seront pas candidates Ă  la compilation mais que seules les fonctions sont concernĂ©es. Les mesures de performances sont prĂ©sentĂ©es avec « [optcarrot](https://github.com/mame/optcarrot) » qui est un Ă©mulateur de console. C’est une bonne chose puisque c’est un cas d’usage rĂ©el (les calculs mathĂ©matiques rĂ©pĂ©titifs sont parfois utilisĂ©s pour les benchmarks de JIT, mais ils sont peu reprĂ©sentatifs car ils leur sont trĂšs favorables). D’un autre cĂŽtĂ©, les exĂ©cutions transactionnelles (typiquement des appels web Ă  un site web en [Ruby On Rails](https://rubyonrails.org/)) seront beaucoup moins sensibles aux amĂ©liorations du JIT. Le JIT n’est pas une nouveautĂ© de Ruby 3.0.0, il a en fait Ă©tĂ© [introduit dans Ruby 2.6](https://www.bigbinary.com/blog/mjit-support-in-ruby-2-6). Autre bonne nouvelle, en Ruby 3.0, la taille du JIT gĂ©nĂ©rĂ© a fortement Ă©tĂ© rĂ©duite ! # DĂ©tails de fonctionnement du MJIT MJIT signifie que ce sont les fonctions qui sont candidates Ă  la compilation. Il s’agit donc de remplacer des fonctions interprĂ©tĂ©es par des fonctions compilĂ©es sur la pile d’appel de fonctions. Le MJIT de Ruby a une approche d’observation. Les mĂ©thodes ne sont pas compilĂ©es de maniĂšre trop optimiste (ce qui semble avoir Ă©tĂ© un reproche Ă  la JVM par le passĂ©, qui se traduisait par un ralentissement au dĂ©marrage) mais les appels de mĂ©thodes sont notĂ©s et aprĂšs plusieurs appels, une fonction est mise en attente « pour compilation ». Les approches pessimistes gĂąchent des gains possibles, les approches optimistes pĂ©nalisent le dĂ©marrage quant aux approches « spĂ©culatives », elles nĂ©cessitent un mĂ©canisme de « dĂ©-optimisation ». Dans la pile d’attente on retrouve les fonctions Ă  optimiser, attendant leur tour pour ĂȘtre compilĂ©es. L’exĂ©cution continue donc en parallĂšle et lorsque la fonction est compilĂ©e par ce processus externe, il peut remplacer la version interprĂ©tĂ©e sur la pile d’appel. La compilation se fait en utilisant un compilateur disponible sur la plateforme. Tout simplement en gĂ©nĂ©rant un code source en C, puis en utilisant GCC pour compiler: ![MJIT queue compilation](https://i.ibb.co/Xtk5n9C/mjitqueue.png) _Image tirĂ©e de [The method JIT compiler for Ruby 2.6](https://k0kubun.medium.com/the-method-jit-compiler-for-ruby-2-6-388ee0989c13) par [k0kubun](https://k0kubun.medium.com/)._ L’avantage de ce processus est sa simplicitĂ© et de pouvoir « s’acheter » facilement de la portabilitĂ© (JIT partout ou GCC est disponible) et Ă©galement de bĂ©nĂ©ficier de l’optimisation de code des compilateurs. Mais cela pose tout de mĂȘme certains problĂšmes : - accĂšs en Ă©criture nĂ©cessaire pour Ruby sur une portion du systĂšme hĂŽte ; - nĂ©cessitĂ© de disposer des outils de dĂ©veloppement sur la machine hĂŽte (vous avez GCC sur vos machines de production ? Pas moi !) # Ractor Ruby 3.0.0 introduit Ă©galement les [Ractor](https://docs.ruby-lang.org/en/3.0.0/doc/ractor_md.html). Il s’agit d’un modĂšle de concurrence basĂ© sur les messages. Les ractors permettent de gĂ©rer plus facilement les exĂ©cutions concurrentes tout en aidant Ă  l’isolation des donnĂ©es. Les ractors sont une *abstraction* de concurrence et ils se veulent thread safe (partagent moins que des threads) sans pour autant le garantir. Chaque ractor possĂšde un ou plusieurs fils d’exĂ©cution. Les Ractor sont expĂ©rimentaux et n’acceptent pas toute la syntaxe Ruby. # Fibers/coroutines Ruby 3.0 introduit Ă©galement de nouvelles mĂ©thodes pour la concurrence lĂ©gĂšre avec des nouvelles routines de contrĂŽle. # Notre Ă©poque sera statique ou ne sera pas Depuis de nombreuses annĂ©es, les langages interprĂ©tĂ©s Ă  typage dynamique proposent des annotations pour donner les types de maniĂšre « statique ». ## RBS Ruby 3.0 Ă©tend sa syntaxe grĂące Ă  RBS qui est une *gem* qui apporte une grammaire de dĂ©finitions. RBS permet d’ajouter la syntaxe pour des types avancĂ©s comme les unions, la surcharge de mĂ©thodes, les gĂ©nĂ©riques ou le *duck typing* avec interfaces. Une dĂ©finition RBS pourra ressembler Ă  ceci : ```ruby # Classes class User attr_reader name : String attr_reader age : Integer def initialize : (name: String, age: Integer) -> [String, Integer] end ``` ## TypeProf TypeProf est un analyseur de programme qui permet de gĂ©nĂ©rer (dĂ©duire) les annotations (la grammaire RBS vue prĂ©cĂ©demment) Ă  partir d’un programme Ruby. TypeProf n’est pas encore compatible avec toute la syntaxe Ruby. À terme, on pourra utiliser le source Ruby avec ses annotations pour faire tout ce qu’on fait habituellement avec de l’analyse statique de code. # Autres nouveautĂ©s de Ruby 3.0.0 L’assignement avec la flĂšche `=>` par exemple `42 => linuxfr`. Nouveau comportement de `in`: - `in` retourne Ă  prĂ©sent un boolĂ©en ; - pour trouver un pattern ; - `case/in` perd son statut « expĂ©rimental ». Nouvelle syntaxe : des mĂ©thodes « sans fin » (sans mot clĂ© `end`) comme par exemple ```ruby def square(x) = x * x ``` # Conclusion Ruby sort donc sa version majeure qui se concentre sur les performances, l’exĂ©cution concurrente et le typage statique. Souhaitons bonne route Ă  la branche 3 de Ruby tout en rappelant que [le site](https://linuxfr.org/) sur lequel vous lisez cette dĂ©pĂȘche est lui-mĂȘme Ă©crit en... [Ruby](https://github.com/linuxfrorg/linuxfr.org) !

AltStyle ă«ă‚ˆăŁăŠć€‰æ›ă•ă‚ŒăŸăƒšăƒŒă‚ž (->ă‚ȘăƒȘă‚žăƒŠăƒ«) /