Salt Okunur Tablolar
Coddy'nin Lua Journey'sinin Object Oriented Programming bölümünün bir parçası — ders 46 / 70.
Closure'lar gerçek gizlilik sağlar, ancak metotların constructor içinde tanımlanmasını gerektirirler. Farklı bir kullanım durumu için başka bir yaklaşım daha vardır: bir nesneyi oluşturulduktan sonra salt okunur hale getirmek. Bu, alanların görünür olmasını ancak değiştirilememesini istediğinizde —sabit bir noktanın koordinatları gibi— kullanışlıdır.
__newindex metametodu, bir tabloya yeni değerler atama girişimlerini yakalar. Tüm atamaları engellemesini sağlayarak bir nesneyi dondurabilirsiniz:
local ImmutablePoint = {}
function ImmutablePoint.new(x, y)
local data = {x = x, y = y}
local proxy = {}
setmetatable(proxy, {
__index = data,
__newindex = function()
error("Cannot modify immutable object")
end
})
return proxy
endİşin püf noktası, bir proxy tablosu kullanmaktır. Asıl veriler data içinde bulunur, kullanıcı ise boş proxy ile etkileşime girer.
Okuma yaparken, __index, data üzerinden veri çeker. Yazma yaparken, bunun yerine __newindex tetiklenir—ve biz bunu engelleriz:
local p = ImmutablePoint.new(10, 20)
print(p.x) -- 10 (okuma çalışıyor)
p.x = 50 -- Hata: Değiştirilemez nesne değiştirilemezBu desen; yapılandırma nesneleri, matematiksel sabitler veya başlatıldıktan sonra asla değişmemesi gereken tüm veriler için değerlidir. Nesne tamamen okunabilir kalır; sadece onu değiştiremezsiniz.
Görev
KolaySalt okunur yapılandırma nesneleri oluşturan bir ImmutableConfig sınıfı oluşturalım! Bu yapılandırma nesneleri bir kez oluşturulduktan sonra, ayarlarının okunmasına izin vermeli ancak bunları değiştirme girişimlerini tamamen engellemelidir.
Kodunuzu iki dosya halinde düzenleyeceksiniz:
ImmutableConfig.lua: Dondurulmuş yapılandırma nesneleri üreten bir modül oluşturun..new(appName, version, maxUsers)fonksiyonunuz bu üç değeri dahili olarak saklamalı, ardından tüm alanların okunmasına izin veren ancak herhangi bir değişikliği önleyen bir proxy tablosu döndürmelidir. Birisi bir değeri değiştirmeye çalıştığında, gerçek bir hata fırlatmak yerineError: Config is read-onlyyazdırmalıdır.main.lua: ImmutableConfig'inizi hayata geçirin! Yapılandırma değerleri için üç girdi okuyun, bir yapılandırma nesnesi oluşturun ve ardından şunları yaparak doğru çalıştığını kanıtlayın:- Üç orijinal değerin tümünü yazdırma
maxUsersalanını değiştirmeye çalışma (bu, hata mesajını tetiklemelidir)- Gerçekten değişmediğini kanıtlamak için
maxUsersdeğerini tekrar yazdırma
Üç girdi alacaksınız:
- Uygulama adı (bir dize)
- Sürüm (bir dize)
- Maksimum kullanıcı sayısı (bir sayı)
Çıktınız yapılandırma değerlerini, değişiklik denendiğinde oluşan hatayı ve değerin değişmeden kaldığının onayını göstermelidir:
App: {appName}
Version: {version}
Max Users: {maxUsers}
Error: Config is read-only
Max Users: {maxUsers}Örneğin, girdiler MyApp, 2.0 ve 100 ise çıktı şöyle olmalıdır:
App: MyApp
Version: 2.0
Max Users: 100
Error: Config is read-only
Max Users: 100Unutmayın: proxy deseni, kullanıcının etkileşime girdiği boş bir tablo kullanırken, gerçek veriler ayrı bir dahili tabloda yaşar. __index metametodu veri tablosundan veri getirir ve __newindex tüm yazma girişimlerini yakalar (ve engeller)!
Kopya kağıdı
__newindex metametodu, bir tabloya yeni değerler atama girişimlerini yakalar. Tüm atamaları engelleyerek, değiştirilemez (salt okunur) nesneler oluşturabilirsiniz:
local ImmutablePoint = {}
function ImmutablePoint.new(x, y)
local data = {x = x, y = y}
local proxy = {}
setmetatable(proxy, {
__index = data,
__newindex = function()
error("Cannot modify immutable object")
end
})
return proxy
endProxy deseni, kullanıcının etkileşime girdiği boş bir tablo (proxy) kullanırken, asıl veriler ayrı bir dahili tabloda (data) tutulur:
__index, okuma yaparken değerleridatatablosundan getirir__newindex, yazma girişimlerini yakalar ve bunları engeller
local p = ImmutablePoint.new(10, 20)
print(p.x) -- 10 (reading works)
p.x = 50 -- Error: Cannot modify immutable objectBu desen; yapılandırma nesneleri, matematiksel sabitler veya başlatıldıktan sonra değişmeden kalması gereken her türlü veri için kullanışlıdır.
Kendin dene
-- ImmutableConfig modülünü içe aktar
local ImmutableConfig = require('ImmutableConfig')
-- Girdileri oku
local appName = io.read()
local version = io.read()
local maxUsers = tonumber(io.read())
-- YAPILACAK: ImmutableConfig.new() kullanarak bir yapılandırma nesnesi oluşturun
-- YAPILACAK: Üç orijinal değerin tümünü şu formatta yazdırın:
-- App: {appName}
-- Version: {version}
-- Max Users: {maxUsers}
-- YAPILACAK: maxUsers alanını değiştirmeyi deneyin (bu bir hata mesajını tetiklemelidir)
-- YAPILACAK: Değiştirilmediğini kanıtlamak için maxUsers'ı tekrar yazdırın
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Object Oriented Programming bölümündeki tüm dersler
1'Self' Kavramı
Fonksiyonlu TablolarAçık 'self'İki Nokta SözdizimiNokta vs İki NoktaÖzet - Hareket Eden Nokta4Proje: Dijital Banka
Proje KurulumuPara Yatırma Metodu7Çok Biçimlilik ve Geçersiz Kılma
Metotları Geçersiz KılmaÜst Sınıf Metotlarını ÇağırmaDuck TypingOrtak ArayüzTür KontrolüÖzet - Çalışan Rolleri2Sınıf Prototip Kalıbı
Prototip Kavramı__index ile Bağlama:new() KurucusuÖznitelikleri BaşlatmaBağımsız ÖrneklerÖzet - Araba Fabrikası5OOP'de Operatör Aşırı Yükleme
Nesneleri ToplamaNesneleri ÇıkarmaNesneleri BirleştirmeNesneleri Karşılaştırma (<, >)Özet - Cüzdan Matematiği8Kapsülleme
Adlandırma KurallarıGizlilik için Closure'larClosure'lar Aracılığıyla ErişimSalt Okunur TablolarDoğrulama MantığıÖzet - Güvenli Kasa11Tasarım Kalıpları (Lite)
Fabrika FonksiyonlarıSingleton TablosuIterator KalıbıObserver (Dinleyici)Özet - Logger Fabrikası3Nesne Durumu ve Davranışı
Örnek DeğişkenleriGetter MetotlarıSetter MetotlarıHesaplanmış ÖzelliklerString BiçimlendirmeEşitlik KontrolleriÖzet - Öğrenci Notu6Kalıtımın Temelleri
Kalıtım KurulumuMetot KalıtımıConstructor'ı GenişletmeAlt Sınıf Metotları EklemePaylaşılan ve BenzersizÖzet - Şekil Hiyerarşisi