I molti interpreti e runtime del linguaggio di programmazione Ruby

Pubblicato: 2022-03-11

introduzione

Proprio come ci sono molte sfumature della gemma Ruby, ci sono molteplici implementazioni dell'interprete Ruby.

L'interprete Ruby più comunemente usato è l'implementazione di riferimento, Ruby MRI, sviluppata in C dal creatore di Ruby (Yukihiro Matsumoto) e dal core team di Ruby.

La nostra Guida all'assunzione di Ruby on Rails menziona che alcuni degli svantaggi di Rails possono essere potenzialmente risolti o evitati utilizzando un interprete Ruby alternativo. Questo articolo mostra le varie implementazioni esistenti dell'interprete Ruby e i runtime disponibili oggi, discutendo i vantaggi e gli svantaggi di ciascuno.

Un elenco di interpreti e runtime di Ruby inclusi mruby, JRuby, RubyMotion, Rubinius e Ruby MRI

Ruby Version History (e come influisce sulle implementazioni alternative)

Purtroppo, non esiste un equivalente del Python Language Reference per Ruby (ISO/IEC 30170:2012 descrive Ruby 1.8 / Ruby 1.9, ma non esistono specifiche corrispondenti per Ruby 2.x). In assenza di tale specifica del linguaggio, gli implementatori di Ruby in genere si affidano invece al RubySpec guidato dalla comunità che specifica i comportamenti previsti del linguaggio Ruby attraverso test che possono essere eseguiti in qualsiasi interprete di Ruby. RubySpec viene quindi utilizzato dagli implementatori di Ruby per verificare la conformità comportamentale delle loro implementazioni Ruby allo standard de facto.

A causa della mancanza di una specifica formale, le nuove versioni di Ruby spesso corrispondono semplicemente alle nuove versioni di Ruby MRI. Vale la pena notare che esiste una questione aperta che discute un processo di progettazione per disaccoppiare Ruby (il linguaggio) dalla risonanza magnetica Ruby.

Dato l'attuale stretto accoppiamento, tuttavia, tra il linguaggio Ruby e l'implementazione di riferimento MRI, gli sviluppatori di implementazioni Ruby alternative a volte faticano a tenere il passo con le modifiche al linguaggio introdotte in ogni nuova versione di MRI.

Non è mai stato così difficile come nella transizione tra Ruby 1.8 e Ruby 1.9. Nel 2007, nel tentativo di ripulire e consolidare la sintassi di Ruby (poiché il linguaggio si era evoluto nel decennio successivo al rilascio di Ruby 1.0), il core team di Ruby ha rilasciato Ruby 1.9.0, una versione che ha introdotto molte incompatibilità con le versioni precedenti nel linguaggio . Di conseguenza, non tutte le implementazioni di Ruby hanno investito lo sforzo necessario per fare il salto sintattico da 1.8 a 1.9. In quanto tali, ci sono diverse implementazioni di Ruby basate su 1.8 che non vengono più utilizzate dalla community, ma che potresti ancora trovare online o di cui si parla da vecchie mani di Ruby.

Una nuova versione di Ruby MRI viene rilasciata ogni Natale, seguendo un principio di versionamento semantico. Ruby 2.0 (rilasciato nel 2013) e 2.1 (rilasciato nel 2014) hanno introdotto ciascuna funzionalità linguistiche aggiuntive che gli sviluppatori di Ruby possono sfruttare, senza perdere la compatibilità con le versioni precedenti con Ruby 1.9.

Perché utilizzare un'implementazione Ruby alternativa? Cosa c'è che non va con la risonanza magnetica?

Ci sono una varietà di implementazioni Ruby alternative, che supportano un'ampia gamma di casi d'uso e ambienti. Ambienti Java Enterprise. Applicazioni mobili. Implementazioni JavaScript. Macchine con poca CPU/RAM. Oltre a supportare questi casi d'uso, le implementazioni alternative a volte possono anche offrire un ulteriore aumento della velocità o un utilizzo più efficiente della memoria, a seconda delle caratteristiche dell'applicazione.

Per molto tempo molti sviluppatori di Ruby on Rails hanno utilizzato Ruby Enterprise Edition (REE) invece di MRI, sfruttando le migliori tecniche di gestione della memoria in REE rispetto alla versione MRI dell'epoca. (REE è stato successivamente interrotto nel 2012.)

Sebbene la risonanza magnetica sia l'implementazione predefinita di Ruby, non è necessariamente la scelta corretta per tutti gli ambienti e gli scenari. Ad esempio, il supporto simultaneo di MRI è inferiore a quello di JRuby o Rubinius. Inoltre, sebbene gli schemi di raccolta dei rifiuti e della memoria della risonanza magnetica siano in costante miglioramento, presentano ancora alcuni problemi.

L'analisi delle implementazioni di Ruby che segue ha lo scopo di assisterti nella selezione dell'interprete più adatto agli obiettivi e ai vincoli operativi del tuo progetto.

Interprete Ruby di Matz (MRI) / CRuby

Scritto in C dal core team di Ruby guidato da Yukihiro Matsumoto ("Matz", il creatore di Ruby), la risonanza magnetica è l'implementazione di riferimento di Ruby che funge da standard de facto. Se un fornitore di sistemi operativi include una versione di Ruby come parte del software installato del sistema operativo, ad esempio, di solito è la versione MRI. MRI beneficia di membri del core team più pagati rispetto a qualsiasi altra implementazione di Ruby, nonché di risorse dedicate da persone o aziende che desiderano migliorare l'ecosistema Ruby.

Ogni Natale viene rilasciata una nuova versione di Ruby MRI, che spesso implementa nuove funzionalità linguistiche, oltre alle modifiche standard della libreria. Le funzionalità vengono implementate prima in Ruby MRI, di solito sulla base delle discussioni sulla mailing list degli sviluppatori principali di Ruby. Altre implementazioni di Ruby sono in ritardo, in alcuni casi anche di anni.

JRuby

JRuby è una versione di Ruby implementata su Java Virtual Machine (JVM). Man mano che diventa popolare per i linguaggi oltre a Java per funzionare su JVM (sto guardando nella tua direzione, Clojure e Scala), è probabile che un'implementazione Ruby basata su JVM guadagnerà popolarità.

Ruby nella JVM significa anche che Ruby può essere eseguito ovunque possa essere eseguito Java (come i telefoni Android, ad esempio utilizzando Ruboto). Inoltre, grazie all'interoperabilità della JVM, il codice JRuby può utilizzare la piattaforma Java, incluse librerie standard e di terze parti.

JRuby è utile anche per portare una soluzione basata su Rails in un ambiente di distribuzione solo Java, impacchettare l'app Rails come file .war da distribuire in un container Tomcat o come applet Java in esecuzione come parte del tuo front-end web , Per esempio.

Per coloro che non sono abituati alla JVM, tuttavia, JRuby offre problemi standard relativi alla JVM come l'avvio lento dell'interprete Ruby, il debug dei problemi di CLASSPATH se stai utilizzando librerie Java di terze parti, un maggiore utilizzo della memoria e il fatto che ora il tuo codice deve essere scritto tenendo presenti le considerazioni sulla sicurezza dei thread.

Inoltre, alcune funzionalità di Ruby (API C e uno dei potenti strumenti di introspezione di Ruby, il modulo ObjectSpace) non sono implementate in JRuby.

Detto questo, i vantaggi dell'utilizzo della JVM possono superare gli svantaggi per determinate situazioni o progetti. La JVM consente molte ottimizzazioni delle prestazioni, come l'attivazione del compilatore JIT o l'utilizzo di API e oggetti Java nativi.

Come esempio di un caso d'uso convincente di JRuby, un mio ex collaboratore una volta ha avuto un problema ad alta intensità di CPU che inizialmente ha risolto con i thread in Ruby 1.9.3. Quando è passato a JRuby e ha utilizzato java.util.concurrent.Executors di Java, ha riscontrato un miglioramento delle prestazioni di più ordini di grandezza (decine di migliaia di volte più veloce) per questa operazione. Guarda il suo esperimento qui.

Rubinio

Rubinius è un'implementazione di Ruby che implementa un runtime generico per linguaggi dinamici su una macchina virtuale di basso livello (LLVM). Utilizzando questa infrastruttura e la tecnologia del compilatore JIT, Rubinius può spesso eseguire codice Ruby con un sovraccarico inferiore rispetto alla risonanza magnetica.

Rubinius è anche costruito usando quanto più Ruby possibile per rendere lo sviluppo dell'interprete/del runtime più veloce e facile.

Curiosità: RubySpec è nato inizialmente nel processo di implementazione di Rubinius.

Come JRuby, Rubinius include un compilatore JIT, una migliore gestione della memoria e una macchina virtuale più matura rispetto a Ruby MRI. Tuttavia, a differenza di JRuby, Rubinius supporta le librerie Ruby C e le basi di Rubinius sono scritte in C++, non in Java.

Rubinius può essere una buona via di mezzo quando hai bisogno di prestazioni elevate sui tuoi server Rails senza la curva di apprendimento o altri svantaggi di JRuby.

rubino

mruby è progettato per essere una versione incorporabile di Ruby (che supporta Ruby 1.9.3). Con mruby, puoi offrire Ruby come linguaggio di scripting/automazione in applicazioni native, utilizzarlo per lo scripting di giochi e persino per programmare schede di microcontrollore come il Raspberry Pi.

Se la tua piattaforma ha severi limiti di risorse, mruby potrebbe essere solo l'interprete di Ruby per te. mruby viene utilizzato anche per:

  • Crea app iOS (come concorrente di RubyMotion, discusso di seguito)
  • Incorpora Ruby nelle app iOS, per la velocità di sviluppo
  • Offri agli utenti finali un linguaggio di scripting incorporato per scopi di automazione

Con l'Internet delle cose che sta diventando sempre più una realtà, l'automazione domestica che si sta affermando e i computer estremamente portatili (e relativamente potenti) sono sempre più comuni, il panorama delle piattaforme target da supportare sta diventando sempre più diversificato. mruby consente di farlo con lo stesso linguaggio produttivo che si utilizzerebbe sul desktop.

Opale

Opal è un transpiler per trasformare Ruby in JavaScript.

Con l'ascesa di Coffeescript, gli sviluppatori stanno imparando che non è necessario digitare JavaScript per ottenere JavaScript. Sebbene Coffeescript abbia certamente i suoi vantaggi, usalo abbastanza a lungo e sei destinato a imbatterti in cose che non ti piacciono della lingua.

Inserisci Opal: digita Ruby, ottieni Javascript . Abbastanza bello.

Opal si sforza di essere il più coerente possibile con altre implementazioni di Ruby ed è quindi testato anche su un sottoinsieme di RubySpec. Tuttavia, esistono alcune incompatibilità derivanti dalla natura dei runtime JavaScript e JavaScript. Ad esempio, stringhe e simboli in Opal sono uguali e Opal non fornisce alcun threading o meccanismo di esecuzione della shell.

Opal funziona in modo autonomo o può essere utilizzato come parte della pipeline di asset Rails (ad esempio, per trasporre automaticamente il tuo file somefile.js.rb in JavaScript).

Forse hai un dominio problematico adatto per il modello di concorrenza asincrona di JavaScript (come un piccolo servizio Node.js) ma desideri la lingua o alcune gemme dallo spazio Ruby. L'opale potrebbe essere una buona soluzione per te in questo caso.

O forse vuoi scrivere un'app Web Ruby completa. Con Opal, puoi. Avere un interprete Ruby che esegue il codice Ruby lato server e quindi avere Opal che genera JavaScript da eseguire sul lato client.

Opal riconosce che probabilmente interagirai con altre API JavaScript (il DOM o Node.js per esempio). Semplifica quindi il passaggio a JavaScript e fornisce un po' di zucchero sintattico Ruby su librerie JavaScript comuni come jQuery.

La natura incentrata su JavaScript di Opal, tuttavia, è sia la sua forza che la sua debolezza. Sul lato negativo, il runtime di Opal è il runtime di JavaScript e Opal è informato dalle decisioni di progettazione di JavaScript. Quindi, se stai cercando una buona implementazione di Ruby con cui scrivere un piccolo script di shell o stai cercando un runtime Ruby migliore per la tua app Rails, Opal probabilmente non è la scelta migliore.

RubyMotion

RubyMotion è sia (a) un'implementazione di Ruby (scritta utilizzando Objective-C e Cocoa) sia (b) un insieme di collegamenti linguistici in modo che gli sviluppatori possano accedere alle API di Cocoa tramite Ruby.

RubyMotion è un prodotto commerciale che ti consente di scrivere app native di Cocoa in Ruby. RubyMotion 2.0 ti consente di scrivere app iOS e Mac OS X in Ruby e RubyMotion 3 promette di portare lo stesso supporto su Android.

RubyMotion implementa la versione 1.9 del linguaggio Ruby.

Implementazioni defunte

Nel corso degli anni dalla prima introduzione di Ruby, alcune delle implementazioni di Ruby che sono venute in essere sono state abbandonate o interrotte, come ad esempio:

  • Ruby Enterprise Edition (REE). REE era un fork di MRI 1.8 della gente di Phusion Passenger che ha implementato molti miglioramenti della memoria e della raccolta dei rifiuti per gli sviluppatori web. Per diversi anni, è stata l'implementazione predefinita di Ruby distribuita per i siti Rails di produzione. Tuttavia, non è mai stato aggiornato per Ruby 1.9 o Ruby 2.0 e alla fine è stato interrotto nel 2012.
  • IronRuby. IronRuby è Ruby implementato su Microsoft .NET, scritto in C#, e per un po' il progetto è stato finanziato da Microsoft. Abbandonato nel 2011, IronRuby ha supportato per l'ultima volta Ruby 1.8.6.

Incartare

C'è un'ampia varietà di runtime e interpreti tra cui scegliere nel panorama di Ruby. Per la maggior parte dei progetti Ruby, l'implementazione di riferimento Ruby (Ruby MRI) rimane l'interprete di scelta. Tuttavia, implementazioni Ruby alternative potrebbero benissimo essere la scelta giusta per il tuo progetto, a seconda dei tuoi obiettivi e vincoli funzionali e tecnici.

Nel suo ruolo di implementazione di riferimento di Ruby, la risonanza magnetica ottiene nuove funzionalità del linguaggio più velocemente, ha una simultaneità e storie di memoria sufficientemente buone (che stanno solo migliorando) e ha la più ampia compatibilità con le gemme (alcune parzialmente scritte in C). Tutto sommato, la risonanza magnetica è una scelta solida e affidabile per il codice Ruby generico.

Per implementazioni aziendali più grandi o per situazioni in cui è necessario interagire con codice Java (o altri linguaggi JVM) o sono necessari modelli di concorrenza altamente evoluti, JRuby è un'opzione interessante.

E ovviamente, se hai esigenze uniche (ad esempio, scrivere JavaScript, eseguire sull'attuale generazione di dispositivi embedded e così via), le altre alternative a Ruby potrebbero essere proprio quello che stai cercando.

Con un'ampia varietà di runtime e interpreti Ruby tra cui scegliere, Ruby si dimostra un linguaggio flessibile, utile per un'ampia gamma di ambienti informatici, che vanno da un grande negozio di distribuzione Java aziendale, al software che controlla il semaforo nel tuo ufficio hai agganciato il tuo Raspberry Pi lo scorso fine settimana. Scegliere lo strumento giusto per lo scopo giusto è essenziale, sì, ma si spera che questo articolo ti abbia mostrato che Ruby è molto più dell'interprete Ruby predefinito fornito con il tuo sistema operativo.

Il mondo di Ruby è notevolmente migliorato dai team di implementazione di Ruby alternativi che lavorano con il team principale di Ruby MRI quando vengono proposte modifiche alla lingua. Aggiungono diversità alla comunità di implementazione di Ruby, aggiungendo le loro esperienze di implementazione Ruby vinte a fatica e le loro prospettive sulle funzionalità che entrano nel linguaggio. Gli appassionati di Ruby devono collettivamente a queste squadre un grande debito di gratitudine. Complimenti a loro per i loro sforzi!