In Ruby, esiste un'ambiguità tra il riferimento a una variabile locale e un messaggio inviato al ricevitore implicito senza un elenco di argomenti. Ciò significa che
foo
possibile media "dereference una variabile locale" o "invia messaggio foo
-self
senza argomenti", vale a dire che potrebbe essere sia equivalente a
binding.local_variable_get(:foo)
o
self.foo()
# or
public_send(:foo)
Questa ambiguità viene risolta al tempo di analisi . Quando il parser incontra un incarico a foo
, da quel momento in poi, considera foo
come una variabile locale, indipendentemente dal fatto che l'assegnazione venga effettivamente eseguita. (Questo è qualcosa che il parser non è in grado di determinare in modo statico, dopo tutto. Basta pensare a if rand > 0.5 then foo = 42 end
.)
In un linguaggio compilato questa non sarebbe nemmeno la compilazione.
Non esiste una lingua compilata. La compilazione e l'interpretazione sono tratti del compilatore o interprete (duh!) Non della lingua. Le lingue non sono né compilate né interpretate. Loro solo sono.
Ogni lingua può essere implementata con un compilatore e ogni lingua può essere implementata con un interprete. La maggior parte delle lingue ha implementazioni compilate e interpretate (ad esempio C ha GCC e Clang, che sono compilatori e Cint e Cling, che sono interpreti, Haskell ha GHC, che è un compilatore, e Hugs, che è un interprete).
Molte implementazioni di linguaggio moderno hanno entrambi nella stessa implementazione, sia in fasi diverse (es. YARV e MRuby compilano Ruby sourcecode al bytecode interno, e quindi interpretano tale codice), o in un motore in modalità mista (ad esempio la HotSpot JVM entrambi interpretano e compila il bytecode JVM, a seconda di quale ha più senso), o entrambi (ad es. Rubinius compila il codice sorgente Ruby in codice bytecode in prima fase, e poi compila il codice bytecode in codice nativo e lo interpreta, a seconda di cosa ha più senso).
Infatti, tutti le implementazioni di Ruby attualmente esistenti sono compilate: YARV e MRuby compilare ai propri formati bytecode interne, Rubinius, MacRuby, MagLev e Topaz compilare ai propri formati bytecode interne, quindi compilare che a nativo codice, JRuby compila in bytecode JVM (che la JVM può o meno compilare ulteriormente), IronRuby compila in bytecode CIL (che il VES può o non può compilare ulteriormente).
Il fatto che Ruby si comporti in questo modo è perché le specifiche del linguaggio dicono così. Non perché Ruby è "interpretato", perché, in realtà, non lo è. L'unica implementazione puramente interpretata di Ruby era la risonanza magnetica e le prime versioni di JRuby, ed entrambi sono stati ritirati da tempo.
È perché Ruby imposta gli ambiti variabili locali in fase di analisi. 'a' è usato come variabile locale in questo ambito, quindi Ruby lo considera come variabile locale (anche se non è mai stato inizializzato). –
@MarekLipka interessante. Ho sentito che potrebbe essere parsing related, ecco perché ho usato il tag AST per questa domanda – jlhonora
Leggilo da http://ruby-doc.org/core-2.1.2/doc/syntax/assignment_rdoc.html#label-Local+ Variabili + e + Metodi –