Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Question about metatables/metamethods, multiple inheritance?

So I'm messing around with metatable's, i understand how setmetatable and __index and __newindex works, but i don't understand inheritance and multiple inheritance yet quite well.

My Problem: I try to get the variable 'h' but it prints nil, everything else is fine, what am i doing wrong here? How can i have nested metatables connected to each other, like fallback when one fails it goes to other.

Here's Code:

local Window = {
	ClassName = 'ScrollingFrame',
	Size = UDim2.new(0,0,0,0),
	CursorColor3 = Color3.fromRGB(255,255,255),
}
Window.__index = Window




Window.metatable = {}
Window.metatable.__index = {
	
	getClassName = function(self)
		return self.ClassName
	end
}
setmetatable(Window, Window.metatable)




--I Can't to seem to get "h" variable from here for some reason?,Why?
Window.LockedProperties = {}
Window.LockedProperties.__index = {h = 999}


setmetatable(Window.metatable, Window.LockedProperties)


--Constructor
function Window.new()
	return setmetatable({},Window)
end


local w = Window.new()


print(w.Size)
print(w.h)
print(w:getClassName())


1 answer

I believe you went about it wrong.

As far as I know, the __index metamethod is supposed to be a function, not a table, which I believe is the main error.

-->> VALUES
local Window = {Size = UDim2.new(0,0,0,0),ClassName = "ScrollingFrame"}
Window.LockedProperties = {h = 999}
Window.__index = Window

-->> FUNCTIONS
Window.Metatable = { -->> one table for everything, no need for heaps
    __index = function(table,index)
        return table.LockedProperties[index]
    end
    -->> you should also use the other function that fires when a value gets set to prevent the locked properties from being changed
}

Window.LockedProperties.__newindex = function(table,index,value)
	warn("Cannot set new value to LockedProperties")
end

setmetatable(Window.LockedProperties,Window.LockedProperties)

setmetatable(Window,Window.Metatable)

function Window.new()
    return setmetatable({},Window)
end

function Window:GetClassName(self)
    return self.ClassName
end

-->> TESTING
local w = Window.new()
print(w.Size,w.h) -->> it should print: 0,0,0,0 999

To explain:

You would want to set everything first so that you know what is where. I like to organise my code when it gets long or complicated - it's very useful.

Next, I create the metatable, and make the __index function that returns the locked property (that's literally it all it needs to do). After that, I simply set the metatable, then create the other functions and methods.

Note that when setting a function inside a table, it will by default be indexed by . and not :. The latter can only be indexed when you set it like I did.

EDITS:

So I tried to come up with a read-only system, but I got stumped. __newindex only fires when a new value and index are created, not when a value is changed. My only other idea is to move the LockedProperties upon creation into a different entity, and index using the table's ID (tostring(table)). But I don't have time to work on that, so good luck ;)


Please comment any problems/questions you have. Hope I helped!

~TDP

4 comments

0

Your Example is printing out nil nil

0

I fixed it by putting (Window.__index = Window) after Window table

0

Could you please post examplewith __newindex where the Window.LockedProperties is locked i tried using __newindex but it throws error trying ot index "new" a nil value

0

Hm alright

This discussion is preserved as it was. New answers, comments, and votes are closed.