Domanda

Nella risposta scelto per questa domanda su Blue rubino , Chuck dice:

  

Tutti della corrente di Ruby   implementazioni vengono compilati a   bytecode. Contrariamente alle affermazioni di SAP, come   di Ruby 1.9, la risonanza magnetica per sé comprende un   compilatore bytecode, anche se la capacità   per salvare il bytecode compilato su disco   scomparso da qualche parte nel processo   di fondere la macchina virtuale YARV.   JRuby è compilato in Java .class   File. Non ho un sacco di dettagli   su MagLev, ma sembra sicuro di dire che   prenderà quella strada pure.

Sono confuso su questo problema di compilazione / interpretazione rispetto a Ruby.

Ho imparato che Ruby è un linguaggio interpretato e per questo quando salvo modifiche ai miei file di Ruby non ho bisogno di ri-costruire il progetto.

Ma se tutte le implementazioni di Ruby ora sono compilati, è ancora giusto dire che Ruby è un linguaggio interpretato? O sto equivoco qualcosa?

È stato utile?

Soluzione

Si, ancora un linguaggio interpretato di Ruby, o più precisamente, di Matz Rubino Interpreter (MRI), che è ciò che la gente di solito parla quando si parla di Ruby, è ancora un interprete. Il passo di compilazione è semplicemente lì per ridurre il codice a qualcosa che è più veloce da eseguire rispetto interpretare e reinterpretare tempo stesso codice dopo volta.

Altri suggerimenti

Quasi ogni lingua è "compilato" al giorno d'oggi, se si contano bytecode come in fase di compilazione. Anche Emacs Lisp viene compilato. Rubino era un caso speciale perché fino a poco tempo fa, non era compilato in bytecode.

Credo che tu abbia ragione a mettere in discussione l'utilità di caratterizzare lingue come "compilato" vs "interpretato". Una distinzione utile, però, è se il linguaggio crea codice macchina (ad esempio assembler x86) direttamente dal codice utente. C, C ++, molti Lisps, e Java con JIT abilitato fare, ma Ruby, Python, Perl e non lo fanno.

Le persone che non conoscono meglio chiameranno qualsiasi linguaggio che ha una fase separata manuale compilation "compilato" e quelli che non "interpretati".

Una sottile domanda davvero ... Ha usato essere che "interpretati" lingue sono stati analizzati e trasformati in una forma intermedia che era più veloce da eseguire, ma la "macchina" di eseguirle era un programma specifico abbastanza la lingua. "Redatto" lingue sono stati tradotti invece nelle istruzioni in codice macchina supportati dal computer su cui è stato eseguito. Una distinzione all'inizio era molto semplice - static vs. scope dinamico. In un linguaggio a tipizzazione statica, un riferimento variabile potrebbe praticamente essere risolto a un indirizzo di memoria in pochi istruzioni macchina - si sapeva esattamente dove nella cornice chiamata la variabile di cui. In linguaggi dinamicamente tipizzati si doveva cercare (di un A-list o di una cornice di chiamata) per il riferimento. Con l'avvento di programmazione orientata agli oggetti, la natura non immediata di un riferimento esteso a molti altri concetti - classi (tipi), metodi (funzioni), anche interpretazione sintattica (DSL embedded come regex).

La distinzione, infatti, tornare a forse 70 fine degli anni non era tanto tra compilato e interpretato lingue , ma se sono stati eseguiti in un ambiente compilato o interpretato. Ad esempio, Pascal (il primo linguaggio ad alto livello ho studiato) ha all'Università di Berkeley prima a Bill Joy pxp interprete, e più tardi il compilatore ha scritto PCC . Stessa lingua, disponibile negli ambienti sia compilati e interpretati.

Alcune lingue sono più dinamici di altri, il significato di qualcosa - un tipo, un metodo, una variabile - dipende l'ambiente run-time. Ciò significa che compilato o non v'è una sostanziale meccanismo runtime associata con l'esecuzione di un programma. Forth, Smalltalk, news, Lisp, tutti erano esempi di questo. Inizialmente, nelle lingue richieste tanto meccanismo per l'esecuzione (rispetto a un C o un Fortran) che erano un naturale per l'interpretazione.

Anche prima Java, ci sono stati tentativi per accelerare l'esecuzione di complessi linguaggi dinamici con trucchi, tecniche che divenne la compilazione filettato, compilazione just-in-time, e così via.

Credo che sia stata Java, però, che era la prima lingua diffusa che in realtà infangato il divario compilatore / interprete, ironia della sorte, non in modo che fosse più veloce (anche se, anche questo), ma in modo che fosse eseguito in tutto il mondo. Definendo il proprio linguaggio macchina e "macchina" il bytecode Java e VM, Java ha tentato di diventare un linguaggio compilato in qualcosa vicino a qualsiasi macchina di base, ma in realtà non qualsiasi macchina reale.

lingue moderne si sposano tutte queste innovazioni. Alcuni hanno la dinamica, aperta, si-non-so-cosa-si-get-fino-runtime natura dei linguaggi tradizionali "interpretato (rubino, Lisp, Smalltalk, Python, Perl (!)), Alcuni cercano di avere il rigore della specifica permettendo tipo a base di rilevamento degli errori statici profonda dei linguaggi tradizionali compilati (Java, Scala). Tutto compilare in rappresentazioni reali indipendenti dalla macchina (JVM) per ottenere la semantica scrivere una volta-run anywhere.

Quindi, contro compilato interpretato? Meglio di entrambi, direi. Tutto intorno il codice sorgente (con documentazione), cambia nulla e l'effetto è immediato, semplici operazioni eseguite quasi veloce come l'hardware può fare di loro, quelli complessi sono supportati e abbastanza veloce, modelli hardware e la memoria sono coerenti tra diverse piattaforme.

La polemica più grande in lingue oggi è probabilmente se sono staticamente o dinamicamente tipizzati, vale a dire che non quanto velocemente faranno correre, ma gli errori si trovano dal compilatore in anticipo (al costo del programmatore dover specificare abbastanza informazioni di battitura complessa) o saranno gli errori venire in fase di test e di produzione.

È possibile eseguire programmi di Ruby in modo interattivo utilizzando irb , l'Interactive Rubino Shell. Anche se può generare bytecode intermedio, non è certamente un "compilatore" nel senso tradizionale.

Un linguaggio compilato è generalmente compilato in codice macchina, al contrario di byte code solo. Alcuni generatori di codice byte può effettivamente compilare ulteriormente il codice byte in codice macchina però.

codice Byte stesso è solo un passaggio intermedio tra il codice letterale scritto dall'utente e la macchina virtuale, deve ancora essere interpretato dalla macchina virtuale se (come si fa con Java in una JVM e PHP con una cache opcode ).

Questa è forse un po 'fuori tema, ma ...

Ferro rubino è un'implementazione basata Netto di rubino e quindi di solito è compilato in codice byte e poi JIT compilato in linguaggio macchina in fase di esecuzione (cioè non interpretato). Anche (almeno con altri linguaggi .NET, quindi immagino che con Ruby) ngen può essere usato per generare un binario nativo compilato prima del tempo, in modo che sia effettivamente una versione codice macchina compilato di codice ruby.

Per quanto riguarda le informazioni che ho ricevuto da RubyConf 2011 a Shanghai, Matz sta sviluppando un 'MRuby' (acronimo di Ruby Matz) per il targeting in esecuzione su dispositivi embedded. E Matz ha detto il il MRuby, fornirà la possibilità di compilare il codice Ruby in codice macchina per aumentare la velocità e diminuire l'utilizzo delle risorse (limitate) sui dispositivi embedded. Così, ci sei vari tipi di implementazione di Ruby e sicuramente non tutti sono appena interpretato durante il runtime.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top