Setter privati
Fa parte della sezione Programmazione orientata agli oggetti del percorso Ruby di Coddy. Lezione 19 di 57.
Spesso un valore dovrebbe essere leggibile da tutti, ma modificabile solo dall'oggetto. attr_reader fornisce il lettore pubblico, mentre private attr_writer un setter che può usare solo l'oggetto. Questo funziona perché attr_writer restituisce i nomi dei metodi che definisce:
class Wallet
attr_reader :balance
def initialize
self.balance = 0
end
def earn(amount)
self.balance = balance + amount
end
private attr_writer :balance
end
w = Wallet.new
w.earn(30)
puts w.balance
begin
w.balance = 1_000_000
rescue NoMethodError => e
puts e.message
endOutput:
30
private method `balance=' called for an instance of WalletUn setter privato viene chiamato con self. all’interno della classe, l’unico ricevente che Ruby accetta per i metodi privati. Senza self. l’assegnazione creerebbe solo una variabile locale:
class Lamp
attr_reader :on
def initialize
self.on = false
end
def toggle
self.on = !on
self
end
private
attr_writer :on
end
puts Lamp.new.toggle.toggle.toggle.onOutput:
truePassare attraverso un setter privato invece di assegnare direttamente @balance mantiene le regole in un unico punto, come un controllo che il valore sia valido:
class Tank
attr_reader :litres
def initialize(capacity)
@capacity = capacity
self.litres = 0
end
def fill(amount)
self.litres = litres + amount
end
def drain(amount)
self.litres = litres - amount
end
private
def litres=(value)
@litres = value.clamp(0, @capacity)
end
end
t = Tank.new(50)
t.fill(80)
puts t.litres
t.drain(70)
puts t.litresOutput:
50
0private attr_accessor :history nasconde sia il metodo di lettura sia il setter, per uno stato interno che il codice esterno non dovrebbe nemmeno vedere:
class Editor
def initialize
self.history = []
end
def type(text)
history << text
end
private attr_accessor :history
endSfida
FacileCompleta la classe Wallet. balance è leggibile dall’esterno ma può essere impostato solo tramite un setter privato, con valore iniziale 0. earn(amount) lo incrementa. spend(amount) lo decrementa e restituisce true, oppure restituisce false senza apportare modifiche quando il saldo è troppo basso. history restituisce il numero di modifiche riuscite, ed è anch’esso protetto da un setter privato.
Il codice fornito legge i comandi +n o -n, stampando balance 30 dopo ciascuno, oppure declined quando una spesa non riesce. Poi stampa changes: 2 e prova wallet.balance = 1000000, stampando cannot set balance quando Ruby rifiuta.
Il tuo codice va in wallet.rb. main.rb contiene il codice di input/output fornito e non può essere modificato.
Provalo tu
require_relative 'wallet'
# Código de entrada/salida proporcionado: déjalo tal como está
input = []
while (line = gets)
input << line.chomp
end
wallet = Wallet.new
input.each do |cmd|
amount = cmd[1..].to_i
if cmd.start_with?("+")
wallet.earn(amount)
puts "balance #{wallet.balance}"
elsif wallet.spend(amount)
puts "balance #{wallet.balance}"
else
puts "declined"
end
end
puts "changes: #{wallet.history}"
begin
wallet.balance = 1_000_000
puts "balance set"
rescue NoMethodError
puts "cannot set balance"
end
Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.
Tutte le lezioni di Programmazione orientata agli oggetti
1Classi e oggetti
Lavorare con i fileDefinire le classiVariabili d'istanzaMetodi e selfto_s e inspectRipasso - Tessera della biblioteca4Incapsulamento
Metodi privatiMetodi protettiSetter privatiProteggere lo statoRiepilogo - Distributore automatico7Polimorfismo e Duck Typing
PolimorfismoDuck TypingMetodi astratticase e classiRiepilogo - Metodi di pagamento10Pattern di progettazione Parte 2
Delegazione con ForwardablePattern DecoratorPattern BuilderPattern State2Metodi di accesso e self
Metodi di lettura e scritturaSetter personalizzatiself nei metodiIdentità e uguaglianzaRiepilogo - Elenco contatti5Ereditarietà
SottoclassiRidefinizione dei metodiChiamare superis_a? e antenatiRiepilogo - Paghe del personale8Metodi speciali
Uguaglianza e hashMetodi degli operatoriIndicizzazione e appendCollezioni personalizzateRiepilogo - Frazioni11Progetto: Gestione della biblioteca
Libri e iscrittiPrendere in prestito i libriEsercitati da solo: Compilatore Ruby online