Custom Functions/Events

That’s because you’re trying to call a workspace function on a table, to fix it you would have to wrap the actual instance method with another function like so:

local methods = {}
methods._extends = workspace -- the "original" instance, this would be constant throughout all of your workspace extensions but if your instance can vary, you will want to define this in your constructor below
function methods:__index(key)
    -- remember 'self' is already defined
    -- case 1, the function exists in the methods table
    if methods[key] then
        return methods[key]
    else
        -- save the member to a variable for readability
        local member = methods._extends[key]
        -- if your instance can vary and is defined per-object, do self._extends[key] instead of methods._extends[key]
        if type(member) == 'function' then
            -- case 2: the member is a function
            return function(_, ...) -- _ in this case would be equal to self
                return member(methods._extends, ...) -- remember to switch to self._extends if the real instance is per-object
            end -- now, this function gets called when called which calls `member` with the proper arguments
        end
        -- case 3: the member is a property, return it
        return member
    end
end

function object.new() -- you can define 'arg' in here if you're passing a varying instance which gets defined per-object
    local newObject = {}
    -- if you are going to pass an object here to extend, you'd do something like
    -- newObject._extends = arg
    return setmetatable(newObject, methods)
end

Not quite, self isn’t defined here. self is just a variable really, it just gets defined automatically when a function is defined with a colon

local blocks = {
    Grass = 10;
    Gold = 20;
}
function blocks:GetGrass() -- remember, defining a function using a colon will assign `self` automatically, in this case, self is blocks
    return self.Grass
end
-- also remember that the above function definition is the exact same as doing this:
function blocks.GetGrass(self)
    return self.Grass
end
-- now, this will not error:
blocks:GetGrass()
2 Likes