Functions aren't saved in a table using metatables (OOP)

Hey there! :smiley:

So, I’ve been working on a module using OOP (Object Oriented Programming), and I am using it to create a “class” which I can create instances of. Here’s an example with the same basic logic as my module:

local Class = {}

-- Create a new class instance.
function Class.new(...)
    local self = setmetatable({}, { __index = Class })
    
    -- Variables set here are saved, and still exist when the class instance is returned.
    self.variable = "This is a test variable."
    
    return self
end

-- This is an example function, which in my case, does not exist in created instances.
function Class:Example()
    print("This is an example function, with no \"real\" logic behind it.")
    return
end

return Class

I’ve been looking into it and I just can’t seem to find an explanation. I’m not extremely experienced with metatables, so it could just be an obvious issue I’m missing. After looking into it a bit, I found similar errors being traced back to BindableEvents, etc., but my module doesn’t really fit into any of those categories.

Edit: Forgot to mention, this class is actually inherited by other class(es), and I have been looking
into those to see if that’s where the error originated!

Either way, I appreciate the help!

Thanks! :smiley:

Can you give an example of what isn’t working? This code looks fine to me.

Also a lot of times people actually stick the __index metamethod inside the Class table itself and reuse it as the metatable. Just saves you an extra table:

local Class = {}
Class.__index = Class

function Class.new(...)
  local self = setmetatable({}, Class)
  --...
  return self
end

But what you did is also fine.

Here’s more info from a great source: Programming in Lua : 16

1 Like

Hey I tried your code out. It worked completely fine. Can you show the script you use the Class?
I inserted the Class as a module script in ServerScriptService.

Here is how I used it in a server script also inserted in the ServerScriptService:

local test = require(game.ServerScriptService.TestClass).new()
test:Example()
print(test.variable)
1 Like

Maybe you’re just confused about why the function isn’t literally in the tables you get from Class.new—that’s because the __index metamethod doesn’t copy anything, it just says “if someone tries to access something in this table that doesn’t exist, try to look it up in this other table instead”

Hey there!

I’m decently aware of this (someone in the Roblox DevForum Community communications server recently explained it to me in depth), but I’m still not sure how it could relate to the functions not being part of the instance of the class. Honestly, I’m pretty much out of ideas to try and fix this :stuck_out_tongue: .

The only thing I can think of is the error can be originating when the class is inherited by another class, but that shouldn’t be occuring since it follows the same metatable logic.

Thanks! :smiley:

What error though? This code seems to work fine.

Hey there!

It errors with “attempt to call a nil value” when I try to call a function from the instance of the class. Not sure why. :stuck_out_tongue:

It’s probably just an obvious mistake on my part, just can’t quite seem to locate what it is.

Thanks! :smiley:

Can you show the code so we can find the mistake?

2 Likes

Hey there!

The module is around 225 lines of code, and is basically one of the main core components of the project, so I’m not quite sure I feel comfortable sharing it completely, but the example I sent has basically the exact same logic as my module.

The only thing I can think of now is that it’s an issue with the inheritance of the class inheriting another, but I’m not sure what would be wrong with it because it uses the same metatable logic, the first argument is just the instance of the original class, and the second is the new class’s __index.

Thanks! :smiley:

The example you sent works, though.

In this article, there is a part where it explains inheritance in Lua OOP. Hope this helps.

1 Like

Are you maybe calling the function with a . instead of a : ?

Hey there!

Yeah, I’m not sure. It’s most likely just an obvious mistake on my part, but I just can’t seem to find where I made the mistake. :stuck_out_tongue:

Thanks! :stuck_out_tongue:

Ok, well not a ton more we can do without code so good luck!

1 Like

I’m not really used to lua classes but I can give you a TS example of a class if you would like to.

https://roblox-ts.com/playground/#code/MYGwhgzhAEDC5WgbwFDXdAthA5gLmgFcA7Aa2IHsB3YlNDYC4iAFwCdDgWK2AKbfETKUaASmT0MGFgAsAlhAB0A6AF4suOlKkAHNnOIteshctyjJ0AL5aMECpgCmAWUeyKAE17jUlm1aA