Özel Atayıcılar
Coddy'nin Ruby Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 19 / 57.
Çoğu zaman bir değer herkes tarafından okunabilmeli, ancak yalnızca nesne tarafından değiştirilebilmelidir. attr_reader herkese açık bir okuyucu, private attr_writer ise yalnızca nesnenin kullanabileceği bir ayarlayıcı sağlar. Bunun nedeni attr_writer metodunun tanımladığı metotların adlarını döndürmesidir:
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
endÇıktı:
30
private method `balance=' called for an instance of WalletÖzel bir setter, sınıfın içinde self. ile çağrılır; Ruby'nin özel metotlar için kabul ettiği tek alıcı budur. self. olmadan atama yalnızca yerel bir değişken oluştururdu:
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.onÇıktı:
true@balance'a doğrudan değer atamak yerine özel bir setter üzerinden geçmek, değerin geçerli olup olmadığını kontrol etmek gibi kurallar için tek bir yer sağlar:
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.litresÇıktı:
50
0private attr_accessor :history, hem okuyucuyu hem de ayarlayıcıyı gizler; böylece dışarıdaki kodun görmemesi gereken dahili durumu saklar:
class Editor
def initialize
self.history = []
end
def type(text)
history << text
end
private attr_accessor :history
endGörev
KolayWallet sınıfını tamamla. balance dışarıdan okunabilir, ancak yalnızca özel bir setter aracılığıyla ayarlanabilir ve başlangıç değeri 0'dır. earn(amount) bu değeri artırır. spend(amount) bu değeri azaltıp true döndürür; bakiye yetersiz olduğunda ise hiçbir değişiklik yapmadan false döndürür. history, yine özel bir setter'ın arkasında tutulan başarılı değişikliklerin sayısını döndürür.
Sağlanan kod +n veya -n komutlarını okur ve her birinin ardından balance 30 yazdırır; harcama başarısız olduğunda ise declined yazdırır. Ardından changes: 2 yazdırır ve wallet.balance = 1000000 atamasını dener; Ruby bu atamayı reddettiğinde cannot set balance yazdırır.
Kodunu wallet.rb dosyasına yaz. main.rb, sağlanan girdi/çıktı kodunu içerir ve düzenlenemez.
Kendin dene
require_relative 'wallet'
# Sağlanan giriş/çıkış kodu: olduğu gibi bırakın
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
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Sınıflar ve Nesneler
Dosyalarla ÇalışmaSınıf TanımlamaÖrnek DeğişkenleriMetotlar ve selfto_s ve inspectÖzet - Kütüphane Kartı7Çok Biçimlilik ve Ördek Tiplemesi
Çok BiçimlilikÖrdek TiplemesiSoyut Metotlarcase ve SınıflarTekrar - Ödeme Yöntemleri2Erişimciler ve self
Okuyucular ve YazıcılarÖzel Setter'larMetotlarda selfKimlik ve EşitlikTekrar - Kişi Listesi5Kalıtım
Alt sınıflarMetotları geçersiz kılmasuper çağrısıis_a? ve üst sınıflarTekrar - Personel Maaşları8Özel Metotlar
Eşitlik ve hashOperatör Metotlarıİndeksleme ve EklemeÖzel KoleksiyonlarTekrar - Kesirler11Proje: Kütüphane Yönetimi
Kitaplar ve ÜyelerKitap Ödünç Alma3Sınıf Metotları ve Değişkenleri
Sınıf MetotlarıSınıf Örnek DeğişkenleriSabitlerFabrika MetotlarıTekrar - Kupon KodlarıKendi başına pratik yap: Online Ruby derleyicisi