Menu
Coddy logo textTech

Tabele tylko do odczytu

Część sekcji Programowanie obiektowe ścieżki Lua w Coddy. Lekcja 46 z 70.

Domknięcia zapewniają prawdziwą prywatność, ale wymagają definiowania metod wewnątrz konstruktora. Istnieje inne podejście do innego zastosowania: utworzenie obiektu tylko do odczytu po jego utworzeniu. Jest to przydatne, gdy chcesz, aby pola były widoczne, ale niezmienialne, na przykład współrzędne stałego punktu.

Metametoda __newindex przechwytuje próby przypisania nowych wartości do tabeli. Blokując wszystkie przypisania, możesz zamrozić obiekt:

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

Sztuczka polega na użyciu tabeli proxy. Rzeczywiste dane znajdują się w data, a użytkownik korzysta z pustej tabeli proxy.

Podczas odczytu __index pobiera dane z data. Podczas zapisu wywoływane jest zamiast tego __newindex, a my to blokujemy:

local p = ImmutablePoint.new(10, 20)
print(p.x)  -- 10 (odczyt działa)
p.x = 50    -- Błąd: Nie można modyfikować niezmiennego obiektu

Ten wzorzec jest przydatny w przypadku obiektów konfiguracyjnych, stałych matematycznych lub dowolnych danych, które nie powinny się zmieniać po inicjalizacji. Obiekt pozostaje w pełni czytelny. Po prostu nie możesz go zmienić.

challenge icon

Wyzwanie

Łatwy

Zbudujmy klasę ImmutableConfig, która tworzy obiekty konfiguracji tylko do odczytu! Po utworzeniu obiekty konfiguracji powinny pozwalać na odczytywanie ustawień, ale całkowicie blokować wszelkie próby ich modyfikacji.

Rozmieścisz swój kod w dwóch plikach:

  • ImmutableConfig.lua: Utwórz moduł, który tworzy zamrożone obiekty konfiguracji. Funkcja .new(appName, version, maxUsers) powinna przechowywać wewnętrznie te trzy wartości, a następnie zwracać tabelę proxy, która umożliwia odczyt wszystkich pól, ale uniemożliwia jakiekolwiek modyfikacje. Gdy ktoś spróbuje zmienić wartość, powinien zostać wyświetlony komunikat Error: Config is read-only, zamiast wystąpić rzeczywisty błąd.
  • main.lua: Ożyw swój ImmutableConfig! Wczytaj trzy wartości wejściowe konfiguracji, utwórz obiekt konfiguracji, a następnie pokaż, że działa poprawnie, wykonując następujące czynności:
    • Wyświetl wszystkie trzy pierwotne wartości
    • Spróbuj zmodyfikować pole maxUsers (co powinno wywołać komunikat o błędzie)
    • Ponownie wyświetl maxUsers, aby udowodnić, że wartość nie została faktycznie zmieniona

Otrzymasz trzy wartości wejściowe:

  1. Nazwa aplikacji (ciąg znaków)
  2. Wersja (ciąg znaków)
  3. Maksymalna liczba użytkowników (liczba)

Wynik powinien pokazywać wartości konfiguracji, błąd występujący przy próbie modyfikacji oraz potwierdzenie, że wartość pozostała niezmieniona:

App: {appName}
Version: {version}
Max Users: {maxUsers}
Error: Config is read-only
Max Users: {maxUsers}

Na przykład, jeśli wartości wejściowe to MyApp, 2.0 i 100, wynik powinien wyglądać następująco:

App: MyApp
Version: 2.0
Max Users: 100
Error: Config is read-only
Max Users: 100

Pamiętaj: wzorzec proxy wykorzystuje pustą tabelę, z którą użytkownik wchodzi w interakcję, podczas gdy właściwe dane znajdują się w osobnej tabeli wewnętrznej. Metametoda __index pobiera dane z tabeli danych, a __newindex przechwytuje (i blokuje) każdą próbę zapisu!

Spróbuj swoich sił

-- Zaimportuj moduł ImmutableConfig
local ImmutableConfig = require('ImmutableConfig')

-- Wczytaj dane wejściowe
local appName = io.read()
local version = io.read()
local maxUsers = tonumber(io.read())

-- TODO: Utwórz obiekt konfiguracyjny za pomocą ImmutableConfig.new()

-- TODO: Wyświetl wszystkie trzy pierwotne wartości w formacie:
-- Aplikacja: {appName}
-- Wersja: {version}
-- Maksymalna liczba użytkowników: {maxUsers}

-- TODO: Spróbuj zmodyfikować pole maxUsers (powinno to wywołać komunikat o błędzie)

-- TODO: Wyświetl ponownie maxUsers, aby potwierdzić, że jego wartość się nie zmieniła
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Lua online