Numeroșii interpreți și timpi de execuție ai limbajului de programare Ruby
Publicat: 2022-03-11Introducere
Așa cum există multe nuanțe ale bijuteriei rubin, există mai multe implementări ale interpretului Ruby.
Cel mai des folosit interpret Ruby este implementarea de referință, Ruby MRI, dezvoltată în C de către creatorul lui Ruby (Yukihiro Matsumoto) și echipa de bază Ruby.
Ghidul nostru de angajare Ruby on Rails menționează că unele dintre dezavantajele din Rails pot fi eventual rezolvate sau evitate prin utilizarea unui interpret Ruby alternativ. Acest articol prezintă diferitele implementări existente de interpret Ruby și runtime disponibile astăzi, discutând avantajele și dezavantajele fiecăreia.
Istoricul versiunilor Ruby (și modul în care acesta afectează implementările alternative)
Din păcate, nu există un echivalent al Referinței limbajului Python pentru Ruby (ISO/IEC 30170:2012 descrie Ruby 1.8 / Ruby 1.9, dar nu există specificații corespunzătoare pentru Ruby 2.x). În absența unei astfel de specificații de limbaj, implementatorii Ruby se bazează de obicei pe RubySpec condus de comunitate, care specifică comportamentele așteptate ale limbajului Ruby prin teste care pot fi rulate în orice interpret Ruby. Prin urmare, RubySpec este folosit de implementatorii Ruby pentru a verifica conformitatea comportamentală a implementărilor lor Ruby cu standardul de facto.
Din cauza lipsei unei specificații formale, noile versiuni ale Ruby adesea corespund pur și simplu noilor versiuni ale Ruby MRI. Este demn de remarcat faptul că există o problemă deschisă care discută un proces de proiectare pentru decuplarea Ruby (limbajul) de RMN-ul Ruby.
Cu toate acestea, având în vedere cuplarea strânsă actuală dintre limbajul Ruby și implementarea de referință MRI, dezvoltatorii de implementări alternative Ruby se luptă uneori să țină pasul cu schimbările de limbaj introduse în fiecare nouă lansare MRI.
Niciodată nu a fost mai greu decât în tranziția dintre Ruby 1.8 și Ruby 1.9. În 2007, într-un efort de a curăța și consolida sintaxa lui Ruby (deoarece limbajul a evoluat în deceniul de la lansarea lui Ruby 1.0), echipa de bază a lui Ruby a lansat Ruby 1.9.0, o versiune care a introdus multe incompatibilități inverse în limbaj. . Ca rezultat, nu toate implementările Ruby au investit efortul necesar pentru a face saltul sintactic de la 1.8 la 1.9. Ca atare, există câteva implementări Ruby bazate pe 1.8 care nu mai sunt folosite de comunitate, dar despre care s-ar putea să le găsiți în continuare online sau despre care vorbesc vechii mâini Ruby.
O nouă versiune de Ruby RMN este lansată în fiecare Crăciun, urmând un principiu semantic de versiuni. Ruby 2.0 (lansat în 2013) și 2.1 (lansat în 2014) au introdus fiecare caracteristici suplimentare de limbaj de care dezvoltatorii Ruby le pot profita, fără a pierde compatibilitatea cu Ruby 1.9.
De ce să folosiți o implementare alternativă Ruby? Ce este în neregulă cu RMN-ul?
Există o varietate de implementări alternative Ruby, care acceptă o gamă largă de cazuri de utilizare și medii. Medii Java Enterprise. Aplicatii mobile. Implementări JavaScript. Mașini CPU/RAM scăzute. Pe lângă sprijinirea acestor cazuri de utilizare, implementările alternative pot oferi uneori și o creștere suplimentară a vitezei sau o utilizare mai eficientă a memoriei, în funcție de caracteristicile aplicației dvs.
Multă vreme mulți dezvoltatori Ruby on Rails au folosit Ruby Enterprise Edition (REE) în loc de RMN, profitând de tehnicile mai bune de gestionare a memoriei din REE în comparație cu versiunea MRI de la acea vreme. (REE a fost ulterior întreruptă, deși în 2012.)
Deși RMN este implementarea implicită Ruby, nu este neapărat alegerea corectă pentru toate mediile și scenariile. De exemplu, suportul de concurență al RMN este inferior celui al lui JRuby sau Rubinius. De asemenea, deși memoria RMN și schemele de colectare a gunoiului se îmbunătățesc în mod constant, acestea au încă unele probleme.
Sondajul implementărilor Ruby care urmează este destinat să vă ajute în selectarea interpretului cel mai potrivit pentru obiectivele și constrângerile operaționale ale proiectului dumneavoastră.
Interpretul lui Matz Ruby (IRM) / CRuby
Scris în C de către echipa principală Ruby condusă de Yukihiro Matsumoto („Matz”, creatorul Ruby), RMN este implementarea de referință a lui Ruby, care servește ca standard de facto. Dacă un furnizor de sistem de operare include o versiune de Ruby ca parte a software-ului instalat de sistemul de operare, de exemplu, este de obicei versiunea RMN. MRI beneficiază de mai mulți membri plătiți ai echipei de bază decât orice altă implementare Ruby, precum și de resurse contribuite dedicate de la oameni sau companii care doresc să îmbunătățească ecosistemul Ruby.
În fiecare Crăciun este lansată o nouă versiune a Ruby MRI – care implementează adesea noi funcții de limbaj, pe lângă modificările standard ale bibliotecii. Caracteristicile sunt implementate mai întâi în Ruby MRI, de obicei pe baza discuțiilor pe lista de corespondență a dezvoltatorilor de bază Ruby. Alte implementări Ruby rămân în urmă, în unele cazuri chiar cu ani.
JRuby
JRuby este o versiune a lui Ruby implementată deasupra mașinii virtuale Java (JVM). Pe măsură ce devine popular ca limbajele dincolo de Java să ruleze peste JVM (mă uit în direcția ta, Clojure și Scala), este probabil ca o implementare Ruby bazată pe JVM să câștige popularitate.
Ruby în JVM înseamnă, de asemenea, că Ruby poate rula oriunde poate rula Java (cum ar fi telefoanele Android, folosind Ruboto, de exemplu). În plus, datorită interoperabilității JVM, codul JRuby poate folosi platforma Java, inclusiv biblioteci standard și terțe.
JRuby este, de asemenea, util pentru a aduce o soluție bazată pe Rails într-un mediu de implementare numai Java, pentru a împacheta aplicația Rails ca fișier .war
pentru a fi implementat într-un container Tomcat sau ca un applet Java care rulează ca parte a front-end-ului dvs. web. , de exemplu.
Pentru cei care nu sunt obișnuiți cu JVM, totuși, JRuby aduce probleme standard legate de JVM, cum ar fi pornirea lentă a interpretului Ruby, problemele de depanare CLASSPATH dacă utilizați biblioteci Java terțe, utilizarea mai mare a memoriei și faptul că acum codul dvs. trebuie scrise ținând cont de considerentele de siguranță ale firelor.
De asemenea, unele caracteristici ale lui Ruby (API-urile C și unul dintre instrumentele puternice de introspecție ale lui Ruby, modulul ObjectSpace) nu sunt implementate în JRuby.
Toate acestea fiind spuse, avantajele utilizării JVM-ului pot depăși dezavantajele pentru anumite situații sau proiecte. JVM permite multe optimizări ale performanței, cum ar fi pornirea compilatorului JIT sau utilizarea obiectelor și API-urilor native Java.
Ca exemplu de caz convingător de utilizare JRuby, un fost coleg de-al meu a avut odată o problemă care consuma mult CPU pe care a rezolvat-o inițial cu fire de execuție în Ruby 1.9.3. Când a trecut la JRuby și a folosit java.util.concurrent.Executors
din Java, a observat o îmbunătățire a performanței de mai multe ordine de mărime (de zeci de mii de ori mai rapid) pentru această operațiune. Vezi aici experimentul lui.
Rubinius
Rubinius este o implementare a lui Ruby care implementează un runtime generic pentru limbaje dinamice pe deasupra unei mașini virtuale de nivel scăzut (LLVM). Folosind această infrastructură și tehnologia de compilare JIT, Rubinius poate rula adesea cod Ruby cu o suprasarcină mai mică decât RMN.

Rubinius este, de asemenea, construit folosind cât mai mult Ruby posibil pentru a face dezvoltarea interpretului / runtime mai rapidă și mai ușoară.
Fapt amuzant: RubySpec a luat ființă inițial în procesul de implementare a Rubinius.
La fel ca JRuby, Rubinius include un compilator JIT, o gestionare mai bună a memoriei și o mașină virtuală mai matură decât Ruby MRI. Cu toate acestea, spre deosebire de JRuby, Rubinius acceptă biblioteci Ruby C, iar bazele lui Rubinius sunt scrise în C++, nu în Java.
Rubinius poate fi o cale de mijloc bună atunci când aveți nevoie de performanță ridicată pe serverele dumneavoastră Rails, fără curba de învățare sau alte dezavantaje ale JRuby.
mruby
mruby este conceput pentru a fi o versiune încorporabilă a lui Ruby (care acceptă Ruby 1.9.3). Cu mruby, puteți oferi Ruby ca limbaj de scripting / automatizare în aplicațiile native, îl puteți utiliza pentru scripting de jocuri și chiar pentru programarea plăcilor de microcontroler precum Raspberry Pi.
Dacă platforma dvs. are constrângeri severe de resurse, mruby poate fi doar interpretul Ruby pentru dvs. mruby este, de asemenea, folosit pentru:
- Creați aplicații iOS (în calitate de concurent al RubyMotion, discutat mai jos)
- Încorporați Ruby în aplicațiile iOS, pentru viteza de dezvoltare
- Oferiți utilizatorilor finali un limbaj de scripting încorporat în scopuri de automatizare
Odată cu Internetul lucrurilor care devine din ce în ce mai mult o realitate, automatizarea locuinței care își face cont și computerele extrem de portabile (și relativ puternice) fiind tot mai obișnuite, peisajul platformelor țintă de suportat devine din ce în ce mai divers. mruby vă ajută să faceți acest lucru cu același limbaj productiv pe care l-ar folosi pe desktop.
Opal
Opal este un transpiler pentru a transforma Ruby în JavaScript.
Odată cu apariția Coffeescript, dezvoltatorii învață că nu trebuie să tastați JavaScript pentru a obține JavaScript. Deși Coffeescript are, desigur, avantajele sale, folosește-l suficient de mult și sigur vei întâlni lucruri care nu-ți plac la limbă.
Introduceți Opal: introduceți Ruby, obțineți Javascript . Destul de la moda.
Opal se străduiește să fie cât mai consistent cu alte implementări Ruby și, prin urmare, este testat și împotriva unui subset de RubySpec. Există totuși unele incompatibilități, care decurg din natura timpilor de execuție JavaScript și JavaScript. De exemplu, șirurile și simbolurile din Opal sunt egale, iar Opal nu oferă niciun mecanism de executare a firelor sau a shell-ului.
Opal rulează de sine stătător sau poate fi folosit ca parte a conductei de active Rails (de exemplu, pentru a transpila automat fișierul somefile.js.rb
în JavaScript).
Poate că aveți un domeniu cu probleme potrivit pentru modelul de concurență asincronă JavaScript (cum ar fi un mic serviciu Node.js), dar doriți limba sau anumite pietre prețioase din spațiul Ruby. Opalul poate fi o soluție bună pentru tine în acest caz.
Sau poate doriți să scrieți o aplicație web Ruby cu stivă completă. Cu Opal, poți. Puneți un interpret Ruby care să ruleze codul dvs. Ruby de pe partea serverului și apoi lăsați Opal să genereze JavaScript pentru a rula pe partea client.
Opal recunoaște că veți interacționa probabil cu alte API-uri JavaScript (DOM-ul sau Node.js, de exemplu). Prin urmare, facilitează tranziția la JavaScript și oferă un nivel sintactic Ruby față de bibliotecile JavaScript comune, cum ar fi jQuery.
Cu toate acestea, natura centrată pe JavaScript a lui Opal este atât puterea, cât și slăbiciunea sa. În dezavantaj, timpul de execuție al lui Opal este timpul de execuție JavaScript, iar Opal este informat de deciziile de proiectare JavaScript. Deci, dacă sunteți în căutarea unei implementări bune a lui Ruby cu care să scrieți un script shell mic sau în căutarea unui timp de rulare Ruby mai bun pentru aplicația dvs. Rails, Opal nu este probabil cea mai bună alegere.
RubyMotion
RubyMotion este atât (a) o implementare Ruby (scrisă folosind Objective-C și Cocoa), cât și (b) un set de legături de limbaj, astfel încât dezvoltatorii să poată accesa API-urile Cocoa prin Ruby.
RubyMotion este un produs comercial care vă permite să scrieți aplicații native Cocoa în Ruby. RubyMotion 2.0 vă permite să scrieți aplicații iOS și Mac OS X în Ruby, iar RubyMotion 3 promite să aducă același suport pentru Android.
RubyMotion implementează versiunea 1.9 a limbajului Ruby.
Implementări defuncte
De-a lungul anilor de când Ruby a fost introdus pentru prima dată, unele dintre implementările Ruby care au apărut au fost abandonate sau întrerupte, cum ar fi:
- Ruby Enterprise Edition (REE). REE a fost un furk al MRI 1.8 de la oamenii de la Phusion Passenger, care a implementat multe îmbunătățiri de memorie și colectare a gunoiului pentru dezvoltatorii web. Timp de câțiva ani, a fost implementarea implicită Ruby implementată pentru site-urile de producție Rails. Totuși, nu a fost actualizat niciodată pentru Ruby 1.9 sau Ruby 2.0 și a fost întrerupt în cele din urmă în 2012.
- IronRuby. IronRuby este Ruby implementat pe Microsoft .NET, scris în C#, iar pentru o perioadă proiectul a fost finanțat de Microsoft. Abandonat în 2011, IronRuby a acceptat ultima dată Ruby 1.8.6.
Învelire
Există o mare varietate de timpi de execuție și interpreți din care să alegeți din peisajul Ruby. Pentru majoritatea proiectelor Ruby, implementarea de referință Ruby (Ruby MRI) rămâne interpretul de alegere. Cu toate acestea, implementările alternative Ruby pot fi foarte bine alegerea potrivită pentru proiectul dvs., în funcție de obiectivele și constrângerile dumneavoastră funcționale și tehnice.
În rolul său de implementare de referință a lui Ruby, RMN obține mai rapid funcții de limbaj noi, are concurență și povești de memorie suficient de bune (care sunt din ce în ce mai bune) și are cea mai largă compatibilitate cu pietre prețioase (unele scrise parțial în C). Una peste alta, RMN-ul este o alegere solidă, de încredere pentru codul Ruby de uz general.
Pentru implementări mai mari, pentru întreprinderi sau pentru situații în care fie trebuie să interacționați cu codul Java (sau alte limbaje JVM) fie aveți nevoie de modele de concurență foarte evoluate, JRuby este o opțiune convingătoare.
Și, desigur, dacă aveți nevoi unice (de exemplu, scrierea JavaScript, rularea pe generația actuală de dispozitive încorporate și așa mai departe), celelalte alternative Ruby pot fi exact ceea ce căutați.
Cu o mare varietate de runtime și interpreți Ruby din care să aleagă, Ruby se arată a fi un limbaj flexibil, util pentru o gamă largă de medii de calcul, variind de la un mare magazin de implementare Java corporativ, până la software care controlează semaforul din biroul dvs. ai conectat Raspberry Pi la weekendul trecut. Alegerea instrumentului potrivit pentru scopul potrivit este esențială, da, dar sperăm că acest articol v-a arătat că Ruby este mult mai mult decât interpretul Ruby implicit care a venit cu sistemul de operare.
Lumea Ruby este mult îmbunătățită de echipele alternative de implementare Ruby care lucrează cu echipa principală Ruby RMN, pe măsură ce sunt propuse modificări ale limbii. Aceștia adaugă diversitate comunității de implementare Ruby, adăugând experiențele lor de implementare Ruby câștigate cu greu și propriile lor perspective asupra caracteristicilor care intră în limbaj. Entuziaștii Ruby le datorează colectiv acestor echipe o mare datorie de recunoștință. Felicitari lor pentru eforturile depuse!