jpott wrote:personally i find it easy to define them, as you would in a class or struct, since i can then look up to the top and easily see how/what i've defined, and don't forget to assign any variables, but I get what you're saying that it isn't necessary.
I know what you mean, sometimes it's more convenient or more readable that way.
it seems metatable and __index will do what I want, but I'm having trouble understanding exactly why it works. Just need to read more i guess.
Yeah, you're on the right track. I'm guessing you come from a (pre-ES6) JS background, given that you mention constructors but not classes. The only reason you can have classless constructors in JS is the magical, non-lexical
this, which is unique to JS as far as I know and is probably the biggest source of confusion and mistakes in that language. Without that, you'll need something to mimic classes; a constructor on its own is meaningless in most languages including Lua.
You can roll your own prototype-based inheritance, which gives you something very similar to what JS has with
new and function prototypes. It goes something like this:
Code: Select all
local MyClass = {} -- the prototype object
function MyClass:init (x, y) self.x, self.y = x, y end
function MyClass:doStuff () end
At this point MyClass is just a regular table with two fields, a function named init and another named doStuff.
Code: Select all
setmetatable(MyClass, {
__call = function (self, ...)
local instance = {}
setmetatable(instance, { __index = self })
instance:init(...)
return instance
end
})
Now we've set a metatable for MyClass and given it a __call metamethod, so we can call it like a function to create an instance of MyClass. The __call metamethod takes the table that was called as the first argument; that is, MyClass. Since MyClass is the prototype for our instances, we create an object and give it a metatable with MyClass as the __index. Then we call the constructor, which is named "init" here but can be whatever you want (just be consistent).
Code: Select all
local instanceOfMyClass = MyClass(1, 2)
Of course you won't want to write all that stuff every time you define a class, so you'll want to move it into a function, maybe add inheritance. Inheritance is just a matter of giving the metatable for MyClass an __index pointing to the supertype.
Hopefully that helps explain some of example code you'll see as you read up on it.