Menu
CoddyTech

Metamethod __newindex

Termasuk bagian Logika dan Alur dalam perjalanan Lua di Coddy. Pelajaran 19 dari 54.

Kamu telah mempelajari cara __index mengendalikan apa yang terjadi saat kamu mencoba membaca kunci yang tidak ada di dalam tabel. Sekarang kamu akan mempelajari pasangannya: __newindex, yang mengendalikan apa yang terjadi saat kamu mencoba menambahkan atau mengubah pasangan kunci-nilai.

Metamethod __newindex dipicu setiap kali kamu mencoba menetapkan nilai ke kunci yang belum ada di tabel. Ini memberimu kemampuan untuk mencegat dan mengendalikan perubahan sebelum terjadi.

Berikut contoh sederhana yang mencegah penambahan kunci baru ke tabel:

local readOnly = {}
local meta = {
    __newindex = function(table, key, value)
        print("Cannot add key: " .. key)
    end
}

setmetatable(readOnly, meta)

readOnly.name = "Alice"  -- output: Cannot add key: name
print(readOnly.name)     -- output: nil

Saat kamu mencoba menetapkan readOnly.name = "Alice", Lua melihat bahwa name tidak ada di tabel. Alih-alih menambahkannya, Lua memanggil fungsi __newindex dengan tiga argumen: tabel itu sendiri, key yang sedang ditetapkan, dan nilai yang ditetapkan.

Dalam contoh ini, fungsi hanya mencetak pesan dan tidak benar-benar menyimpan apa pun.

Kamu juga bisa menggunakan __newindex untuk memvalidasi data sebelum mengizinkannya masuk ke tabelmu:

local player = {}
local meta = {
    __newindex = function(t, key, value)
        if key == "health" and type(value) ~= "number" then
            print("Health must be a number!")
        else
            rawset(t, key, value)
        end
    end
}

setmetatable(player, meta)

player.health = "high"  -- output: Health must be a number!
player.health = 100     -- Diizinkan

Perhatikan penggunaan rawset() pada contoh kedua. Fungsi ini melewati metatable dan langsung menetapkan nilai di dalam tabel.

Tanpanya, mengatur nilai akan memicu __newindex lagi dan menciptakan perulangan tanpa akhir.

challenge icon

Tantangan

Mudah
Tulis fungsi createValidatedTable yang menerima key dan value, lalu mengembalikan tabel yang hanya menerima nilai string untuk key baru.

Buat tabel kosong dan pasangkan metatable dengan __newindex yang memvalidasi tipe nilai. Jika seseorang mencoba menambahkan nilai non-string, gunakan rawset() untuk menyimpan string "invalid" sebagai gantinya. Untuk nilai string, simpan nilai tersebut seperti biasa menggunakan rawset().

Logika:

  • Buat tabel kosong
  • Buat metatable dengan __newindex yang menerima tabel, key, dan value
  • Di dalam __newindex, periksa apakah value berupa string menggunakan type(value) == "string"
  • Jika berupa string, gunakan rawset(t, key, value) untuk menyimpannya
  • Jika bukan string, gunakan rawset(t, key, "invalid") untuk menyimpan "invalid" sebagai gantinya
  • Pasangkan metatable ke tabel menggunakan setmetatable()
  • Gunakan rawset() untuk menambahkan pasangan key-value awal ke tabel, dengan melewati metatable
  • Kembalikan tabel

Parameter:

  • key (string): Key awal yang akan ditambahkan ke tabel
  • value (string): Nilai awal yang akan ditambahkan ke tabel

Nilai yang dikembalikan: Tabel dengan validasi yang hanya menerima nilai string, berisi pasangan key-value awal (tabel)

Coba sendiri

function createValidatedTable(key, value)
    -- Tulis kodemu di sini
end
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Logika dan Alur

Latihan sendiri: Compiler Lua online