Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Question about metatables/metamethods, multiple inheritance?

Asked by 7 years ago

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

Log in to vote
0
Answered by 7 years ago
Edited 7 years ago

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

0
Your Example is printing out nil nil mastermarkus 11 — 7y
0
I fixed it by putting (Window.__index = Window) after Window table mastermarkus 11 — 7y
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 mastermarkus 11 — 7y
0
Hm alright TheDeadlyPanther 2460 — 7y
Ad

Answer this question