Prywatne settery
Część sekcji Programowanie obiektowe ścieżki Ruby w Coddy. Lekcja 19 z 57.
Często wartość powinna być dostępna do odczytu dla wszystkich, ale zmieniana tylko przez obiekt. attr_reader udostępnia publiczny odczyt, a private attr_writer — metodę ustawiającą, z której może korzystać tylko obiekt. Działa to dlatego, że attr_writer zwraca nazwy metod, które definiuje:
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
endWynik:
30
private method `balance=' called for an instance of WalletPrywatny setter jest wywoływany za pomocą self. wewnątrz klasy — to jedyny odbiorca, którego Ruby dopuszcza w przypadku metod prywatnych. Bez self. przypisanie utworzyłoby jedynie zmienną lokalną:
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.onWynik:
trueKorzystanie z prywatnego settera zamiast bezpośredniego przypisywania wartości do @balance pozwala umieścić reguły w jednym miejscu, na przykład sprawdzenie, czy wartość jest prawidłowa:
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.litresWynik:
50
0private attr_accessor :history ukrywa zarówno metodę odczytującą, jak i ustawiającą, w przypadku stanu wewnętrznego, którego kod zewnętrzny nie powinien nawet widzieć:
class Editor
def initialize
self.history = []
end
def type(text)
history << text
end
private attr_accessor :history
endWyzwanie
ŁatwyUzupełnij klasę Wallet. balance można odczytać z zewnątrz, ale ustawiać tylko za pomocą prywatnego settera; jego początkowa wartość to 0. earn(amount) dodaje do niego podaną wartość. spend(amount) odejmuje podaną wartość i zwraca true albo zwraca false bez wprowadzania zmian, gdy saldo jest zbyt niskie. history zwraca liczbę udanych zmian i również jest chronione przez prywatny setter.
Dostarczony kod odczytuje polecenia +n lub -n, po każdym wypisując balance 30, a gdy operacja wydania środków się nie powiedzie — declined. Następnie wypisuje changes: 2 i próbuje wykonać wallet.balance = 1000000, wypisując cannot set balance, gdy Ruby odrzuci tę próbę.
Twój kod umieść w pliku wallet.rb. Plik main.rb zawiera dostarczony kod wejścia/wyjścia i nie można go edytować.
Spróbuj swoich sił
require_relative 'wallet'
# Dostarczony kod wejścia/wyjścia: pozostaw go bez zmian
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
Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.
Wszystkie lekcje w sekcji Programowanie obiektowe
1Klasy i obiekty
Praca z plikamiDefiniowanie klasZmienne instancjiMetody i selfto_s i inspectPowtórzenie – karta biblioteczna4Hermetyzacja
Metody prywatneMetody chronionePrywatne setteryOchrona stanuPowtórzenie – automat vendingowy7Polimorfizm i typowanie kacze
PolimorfizmTypowanie kaczeMetody abstrakcyjnecase i klasyPowtórzenie – metody płatności10Wzorce projektowe, część 2
Delegowanie z ForwardableWzorzec dekoratoraWzorzec budowniczegoWzorzec stanu2Metody dostępowe i self
Gettery i setteryWłasne setteryself w metodachTożsamość i równośćPowtórzenie – lista kontaktów5Dziedziczenie
PodklasyNadpisywanie metodWywoływanie superis_a? i przodkowiePowtórka – lista płac pracowników8Metody specjalne
Równość i hashMetody operatorówIndeksowanie i dodawanieWłasne kolekcjePowtórka – ułamki11Projekt: Zarządzanie biblioteką
Książki i czytelnicyWypożyczanie książekPoćwicz samodzielnie: Kompilator Ruby online