2013-02-23 17 views
5

Ho imparato Ruby e Python contemporaneamente e una delle cose che ho notato è che queste 2 lingue sembrano trattare l'ambito in modo diverso. Ecco un esempio di ciò che intendo:Ambito in Ruby e Python

# Python 
a = 5 
def myfunc(): 
    print a 

myfunc() # => Successfully prints 5 

# Ruby 
a = 5 
def myfunc 
    puts a 
end 

myfunC# => Throws a "NameError: undefined local variable or method `a' for main:Object" 

sembra che blocco DEF può accedere alle variabili dichiarate al di fuori del suo campo di applicazione immediata in Python, ma non in Ruby. Qualcuno può confermare se la mia comprensione è corretta? E se sì, se uno di questi modi di pensare allo scopo è più comune nella programmazione?

+0

Per il lato Python, hai ragione (c'è ovviamente più per l'ambito, ma il tuo fraseggio non ne contraddice). – delnan

+0

Risposta di Python possibile qui: http://stackoverflow.com/questions/370357/python-variable-scope-question –

risposta

4

Disclaimer: io non sono un esperto di pitone

In Python, dove le variabili definite in un modulo sono, per impostazione predefinita, le variabili di modulo e come tale globale per quel modulo. In Ruby, quando si definisce una variabile minuscola, è sempre una variabile locale. Le variabili locali sono accessibili solo nel blocco che le ha definite e in procs/lambdas definite in quel blocco che include la variabile.

In Ruby, per una variabile da attraversare ambiti, essa deve essere:

  • Una costante (ALL_CAPS): Sempre accessibile, se preceduto dal perimetro destra
  • variabile Class (@@double_at): Sempre accessibile dalla classe di definizione e da qualsiasi sottoclasse, ma non dall'esterno
  • Variabile di istanza (@single_at): accessibile solo dall'interno di tale oggetto e dall'esterno con metodi getter/get_instance_variable.
  • Globale ($starts_with_dollar): una cattiva idea. Attraversa tutti gli ambiti, non è necessario l'ambito. Non usare!
+0

Ah, vedo, quindi per Python, quando si definisce una variabile al di fuori di qualsiasi classe o blocco, per impostazione predefinita sarà nell'ambito globale. Ciò contrasta con Ruby in cui Ruby tratta ogni ambito come una propria entità separata e si definiscono le variabili globali accessibili in tutti gli ambiti tramite l'utilizzo di $. È un riassunto accurato? – wmock

+0

@WillsonMock: praticamente. – Linuxios

+2

Minor nitpick: le costanti non sono ALL_CAPS, iniziano solo con una lettera maiuscola. I nomi di classe, ad esempio, sono costanti. – steenslag

1

In Ruby se si desidera accedere a una variabile definita al di fuori del metodo che si sta invocando, è necessario definirla come globale. Ruby tenta di far corrispondere la variabile definita nello scope locale, se non la trova, genera un'eccezione.

È possibile definire una variabile globale con il segno $.

$a = 5 
def myfunc 
    puts $a 
end 

myfunc 

Tuttavia come regola generale non è una buona pratica definire le variabili globali altrimenti rischierà di inquinare lo spazio dei nomi globale.

+3

Questo è assolutamente sbagliato. Una variabile di istanza ('@ a') è sufficiente. – steenslag

1

È possibile utilizzare il modulo dis per vedere cosa sta facendo Python.

import dis 

a = 5 
def myfunc(): 
    print a 

Risultato:

>>> dis.dis(myfunc) 
15   0 LOAD_GLOBAL    0 (a) 
       3 PRINT_ITEM   
       4 PRINT_NEWLINE  
       5 LOAD_CONST    0 (None) 
       8 RETURN_VALUE 

Così si può vedere che è a nell'ambito globale.