2012-03-12 17 views
34

Ho il seguente codice Ruby:variabile locale Rubino è indefinito

local_var = "Hello" 

def hello 
    puts local_var 
end 

hello 

ottengo il seguente errore:

local_variables.rb:4:in 'hello': undefined local variable or method 'local_var' 
for main:Object (NameError) from local_variables.rb:7:in '<main>' 

Ho sempre pensato che le variabili locali non sono accessibili dall'esterno del blocco, funzione, chiusura, ecc.

Ma ora ho definito la variabile locale nel file e provo ad ottenere un accesso dalla funzione INSIDE s file ame.

Cosa c'è di sbagliato nella mia comprensione?

+1

Hai detto "Ho sempre pensato che le variabili locali non siano accessibili dall'esterno [...] della funzione". Quindi, perché sei sorpreso che la tua variabile locale stia guardando solo all'interno della funzione sulla linea 'puts'? – Gareth

+4

perché gli altri linguaggi di programmazione differiscono – shevchyk

+1

try @local_var = "Hello" –

risposta

51

In variabili locali Ruby accessibili solo nell'ambito che sono definite. Ogni volta che si entra/si abbandona una classe, un modulo o un metodo definiscono le proprie oscillazioni in Ruby.

Per esempio:

v1 = 1 

class MyClass # SCOPE GATE: entering class 
    v2 = 2 
    local_variables # => ["v2"] 

    def my_method # SCOPE GATE: entering def 
    v3 = 3 
    local_variables # => ["v3"] 
    end # SCOPE GATE: leaving def 

    local_variables # => ["v2"] 
end # SCOPE GATE: leaving class 

Questi punti che entrano ed escono sono chiamati Ambito Gates. Poiché entri attraverso Scope Gate tramite la definizione del metodo, non puoi accedere al tuo local_var all'interno del metodo hello.


È possibile utilizzare Ambito Appiattimento concetto passare la variabile attraverso queste porte.

Ad esempio anziché utilizzare def per definire il metodo è possibile utilizzare Module#define_method.

local_var = "Hello" 

define_method :hello do 
    puts local_var 
end 

Allo stesso modo è possibile definire le classi di via Class#New in modo che il campo di applicazione non cambia quando si passa attraverso la definizione di classe.

local_var = 'test' 

MyClass = Class.new do 
    puts local_var #valid 
end 

invece di

class MyClass 
    puts local_var #invalid 
end 

Allo stesso modo si dovrebbe usare Module#New se si desidera passare le variabili locali attraverso i cancelli del modulo.

esempio è preso dal Metaprogramming Ruby

-7

local_var è una variabile locale. Le variabili locali sono locali rispetto all'ambito in cui sono definite. (Ecco perché sono chiamate "variabili locali", dopotutto!) Quindi, ovviamente, poiché local_var è definito nell'ambito dello script, non è possibile accedervi nell'ambito del metodo .

+20

Se sono in una macchina e ho un cambio nella mia tasca, poi c'è un cambio nell'auto. Molti altri linguaggi inoltrano variabili locali a scopi interni, quindi non c'è motivo di considerare il comportamento di Ruby come ovvio. –

+0

@AdamTolley hai perfettamente ragione, ma immagino che Ruby potrebbe essere la prima lingua di Jorg e che l'ambito potrebbe sembrare ovvio per lui! –

+0

@AlexanderSuraphel: In realtà, si trattava della mia quindicesima lingua, anche se per il momento in cui scrissi quella risposta, probabilmente ne avevo un'altra dozzina. Non tengo davvero traccia. –