Problems with metatables

I have a problem where the metatable is not identified, if you look at the code below and test it you will notice that it will not print the value described in metaTable.__newindex.

local metaTable = {}
metaTable.__index = metaTable

function metaTable.__newindex(self, index, value) 
  print(index, value)
  rawset(self, index, value) 
end

local Table = {}
Table.Cat = setmetatable({ 
  Health = 7, 
  MaxHealth = 9 
}, metaTable)

Table.Cat.Health = 1

print(Table)

you used __index, not __newindex, also, you’re misunderstanding how both work

__index triggers when you reference a value that doesnt exist in the table, like print(Table.Cat.Banana)

__newindex triggers when you set a value that doesnt exist in the table, like Table.Cat.Banana = 1

in your case, you set Health, which is already defined in the table, so neither of the metamethods would be triggered


if you’re trying to do something like print whenever health changes, kinda like an event, I would do this

local playerData = {
   rawData = {
      health = 10,
      maxHealth = 10,
   },
}
local metaMethods = {
   __newindex = function(self, index, newValue)
      print("Attempting to change", index, "to", newValue, "from", self.rawData[index])
      self.rawData[index] = newValue
   end,
   __index = function(self, index)
      print("Attempting to get", index)
      return self.rawData[index]
   end
}
local player = setmetatable(playerData, metaMethods)

print(player.health)
player.health = 5
print(player.health)
1 Like

Well, I already knew about the .newindex and .index functions, but my error was occurring when trying to identify a change in values ​​in the metatable. By the way, your code may cause a looping error, after all you defined the indexing function and then indexed a value, the same is repeated with new indexes.

I solved my problem by doing this:

local MetaTable = {}

function MetaTable.__index(self, index)
	return self.__cache[index]
end

function MetaTable.__newindex(self, index, value)
	rawset(self.__cache, index, value)
end

local MyTable = setmetatable({ __cache = {} }, MetaTable)

Anyway, thanks for your reply! :wink:

1 Like

__index doesn’t trigger when you access a value that already exists, so it wouldnt loop in that case

No, __cache is a value that is already defined in the table, .index only identifies values ​​not yet assigned.

yea, so because the __index and __newindex functions I setup don’t reference values not yet assigned in the table, it won’t infinitely loop

Omg friend! Thank you friend this is so helpful friend please keep helping

Gior piece friend local windstween = windstween.new(GiorPiece)