Le variabili di istanza non sono visibili al di fuori della classe.
class MyClass
def initialize
@message = "Hello"
end
end
msg = MyClass.new
@message
#==> nil # This @message belongs to the global object, not msg
msg.message
#==> NoMethodError: undefined method `message'
[email protected]
#==> SyntaxError: syntax error, unexpected tIVAR
Ora, si può sempre fare questo:
msg.instance_eval { @message }
Ma questo è scomodo e cheatish. Giocare attorno alla classe di qualcun altro può essere educativo, ma il codice del tuo cliente non dovrebbe farlo se vuoi ottenere risultati affidabili. Il rovescio della medaglia, se vuoi che i client siano in grado di vedere quei valori, non farli usare instance_eval
; invece, definire un metodo che fa il trucco:
class MyClass
def message
return @message
end
end
msg.message
# ==> "Hello"
Perché così spesso vuole fare questo, Ruby fornisce un collegamento per rendere più facile. Il seguente codice ha esattamente lo stesso risultato del codice sopra riportato:
class MyClass
attr_reader :message
end
Questo non è un nuovo tipo di variabile; è solo un modo stenografico per definire il metodo. Puoi guardare msg.methods
e vedere che ora ha un metodo message
.
Ora, che cosa succede se si desidera consentire agli estranei di non solo visualizzare il valore di una variabile di istanza, ma anche di modificarlo? Per questo, è necessario definire un metodo diverso per l'assegnazione, con un =
nel nome:
class MyClass
def message=(new_value)
@message = new_value
end
end
msg.message = "Good-bye"
msg.message
# ==> "Good-bye"
Nota che gli operatori di assegnazione sono semi-magica qui; anche se c'è uno spazio tra e =
, Ruby sa ancora chiamare il metodo message=
. Gli operatori di combinazione come +=
e così via attiveranno anche le chiamate al metodo.
Ancora una volta, questo è un disegno comune, in modo Rubino offre una scorciatoia per esso, anche:
class MyClass
attr_writer :message
end
Ora, se si utilizza attr_writer
di per sé, si ottiene un attributo che può essere modificato, ma non si vede . Ci sono alcuni casi di utilizzo dispari in cui è quello che vuoi, ma il più delle volte, se hai intenzione di permettere agli estranei di modificare la variabile, vuoi che siano in grado di leggerla anche tu. Invece di dover dichiarare sia un attr_reader
ed un attr_writer
, è possibile dichiarare entrambi contemporaneamente in questo modo:
class MyClass
attr_accessor :message
end
Ancora una volta, questo è solo una scorciatoia per la definizione di metodi che consentono di ottenere alla variabile di istanza al di fuori della classe.
'attr_accessor' creerà una variabile di istanza, i metodi _plus_ per leggere e scrivere la variabile di istanza. –
In realtà, @AlexWayne, 'attr_accessor' dichiara solo i metodi. Le variabili di istanza non devono essere dichiarate; sorgono quando si tenta di accedervi (e il loro valore è 'nil' se quel primo accesso è una lettura anziché una scrittura). –