Diverse variabili si comportano in modo diverso in Ruby, ma nessuna di esse ha bisogno di una dichiarazione esplicita.
Il comportamento più interessante è per le variabili locali: Ruby ti permette di lasciare il ricevitore per un messaggio inviato a self ( self è il ricevitore implicito), quindi foo() è la stessa cosa di self.foo() e consente anche di escludere l'elenco degli argomenti se non ci sono argomenti, quindi foo.bar è la stessa cosa di foo.bar() ; mettendo insieme i due, otteniamo che foo è la stessa cosa di self.foo() , cioè un messaggio invia senza argomenti al ricevitore implicito self . Potrebbe, tuttavia, essere anche un riferimento alla variabile locale foo . Questa ambiguità è risolta nel modo seguente: foo è interpretato come un messaggio di invio, a meno che un assegnamento a foo sia stato analizzato (ma non necessariamente eseguito ) prima, quindi da quel punto in poi viene interpretato come una variabile locale.
Questa è la cosa più vicina che Ruby deve alla dichiarazione di variabile:
foo
# NameError: undefined local variable or method 'foo'
defined?(foo)
# => nil
def foo; 23 end
foo
# => 23
defined?(foo)
# => 'method'
methods
# => [:foo, …]
if false then foo = 42 end
foo
# => nil
defined?(foo)
# => 'local-variable'
local_variables
# => [:foo]
Si noti che NameError è not generato perché la variabile locale non è definita, ma poiché Ruby non sa cosa fare dell'espressione: è una variabile locale o una chiamata di metodo?
Le variabili di istanza e le variabili globali si comportano in modo simile, valutano a nil anche se non sono definite:
@foo
# => nil
defined?(@foo)
# => nil
@foo = 42
@foo
# => 42
defined?(@foo)
# => 'instance-variable'
instance_variables
# => [:@foo]
$foo
# => nil
defined?($foo)
# => nil
$foo = 42
$foo
# => 42
defined?($foo)
# => 'global-variable'
global_variables
# => [:$foo, …]
Le variabili e le costanti della gerarchia di classe si comportano diversamente, aumentano NameError se non sono definite:
@@foo
# NameError
defined?(@@foo)
# => nil
@@foo = 42
@@foo
# => 42
defined?(@@foo)
# => 'class-variable'
self.class.class_variables
# => [:@@foo]
FOO
# NameError
defined?(FOO)
# => nil
FOO = 42
FOO
# => 42
defined?(FOO)
# => 'constant'
self.class.constants
# => [:FOO]