All about Object Oriented Programming

I haven’t tried OOP with Lua yet, since most of my projects use a singleton format. So I’d have to ask: since OOP is becoming increasingly part and parcel to the Rōblox development scene, has someone yet written a library that simplifies class implementations?

My thoughts are that it could extend on the principle TypeScript uses to simplify constructors:

class foo {
constructor(name:string){}
}

I did create an OOP library called “AntWorks” it’s very simple to use. [AntWorks - Object Oriented Library for rbxLua]

1 Like

There are many libraries available however I’d advise you to consider the consequences of using a library before just diving in.

What I consider to be the main strength with this way of doing OOP in Lua is that is has no external dependencies. Once you have external dependencies you have to drag them around wherever your scripts go, you are locked into their way of doing things and it is more difficult to refactor later. This is not necessarily a bad thing if you don’t mind that, but it is important to consider. Make sure, if you accept these disadvantages, that the advantages are comparatively worth it.

Now there are a large range of libraries/tools available, from tiny little ones which just give you slightly cleaner syntax, large ones which automatically give you cool features such as reflection information and huge ones which completely transform the language!

One such library/tool which you might be interested in due to your mention of TypeScript is roblox-ts which effectively lets you use TypeScript in Roblox. It is still in development so it is advised to only use it for experimentation however it is quite amazing.

1 Like

That’s why I couldn’t consider using larger dependencies (such as Roact) yet. One that creates a shortcut for initialising classes wouldn’t require a drastically new way of doing a major process. In fact, I had used to include a huge library of functions I made that took so long to prepare that it would time out before the actual script run.

Yes, I am aware of roblox.ts.

There doesn’t seem to be an answer so I’ll post it:

Connections to object methods

I haven’t found an elegant way of handling this since the parameters passed by the connection are not related to the object itself, the simplest way I’ve come up with is to have an object method that returns a function, which is then connected to, like so:

function Obj:eat()
    return function()
        print("eated")
    end
end

local a = Obj.new()
a.Value.Changed:connect(a:eat())

Has anyone come up with a better way?

1 Like

The way I’ve seen it done in other languages, is with a function called bind (see: Javascript Function.prototype.bind() and C++ std::bind()). In Lua a simple version could look something like this:

local function bind(method, obj)
	return function(...)
		return method(obj, ...)
	end
end

function Obj:eat()
	print("eated")
end

local a = Obj.new()
a.Value.Changed:connect(bind(Obj.eat, a))
4 Likes

Wow, at first I was intimidated by OOP with all the metatables and everything. But then, after reading your thread, it cleared up some of my questions about it. Now, I truly see how this is super useful. I can’t wait to use it!

Thank you so much for taking your time to write this, it helps a lot! :smile:

4 Likes

This tutorial was amazing. It helps to better understand OOP and now I use it often. Definitely recommend for anyone new to OOP.

Great tutorial!

2 Likes

Thank you, I can finally flex on my friends with this new knowledge. :+1:

THANK YOU :heart:
Thank you, this was very helpful. I already knew OOP from Java, though by just reading some scripts utilizing it I didn’t understand it. You were my rescue. Thanks, man.

1 Like

This is super well explained however I don’t understand what do the 5th line in the last block of code. I tough the syntax was setmetatable(<table>, <metamethod>)

… sets the meta-table of Truck to be the table Car which has its own meta-tables already defined.

OP describes this when they introduce a short description of meta-tables easier in the post:

In these examples, new instances of Car (such as newCar) and new classes that extend Car (such as Truck) will all use the meta-tables defined in Car.

1 Like

Couldn’t find anything related to this:
How would you go about doing private properties?

Private properties are only applicable to inheritance, and would be overkill in Lua.

Trust me, I’m the king of overkill. Eight years ago I made some pretty sophisticated OOP logic for Lua, and it was quite a challenge to figure out the best implementation.

2 Likes

https://www.lua.org/pil/6.1.html
Closures, perhaps?

How do I apply these technique to instance?

So I’m still a bit confused on __index.

So far this is what I understand:

If you’re looking for a certain item in a table and it does not exist, __index will “fire” and redirect it to the proper area (I think?). Anyways, why do you do

Car.__index = Car

Basically, whats the point of setting Car’s __index to Car again? Wouldn’t that theoretically just start an endless loop with the Car table?

Keep in mind the distinction between a metatable and a table. You can think of a metatable as a list of events for a table. The car table is the metatable, not the table being indexed. So if we have a car object we set it’s metatable to Car with setmetatable({}, Car). This means when we do a function call it looks into, in this case, an empty table so fires the __index metamethod which redirects it to Car. Conveniently Car is where we defined all of our functions! This is nice as it means we only need one copy of the functions, instead of putting them inside every object.

The circular case you are imagining would be setmetatable(Car, Car).

3 Likes
local NpcModule = {}
	NpcModule.__index = NpcModule

function NpcModule.New(Name, Job, Age)
	local NewNpc = {}
	setmetatable(NewNpc, NpcModule)
	
	NewNpc.Name = Name
	NewNpc.Job = Job
	NewNpc.Age = Age
	
	return NewNpc
end

Npc = {}
for i = 1, 5 do
   Npc[i] = NpcModule.New(RandomName, RandomJob, RandomAge)
end

return NpcModule

I’m trying to do a Database, did you have any idea how I store Npcs data?

You just made my day.

You article does a great job of explaining how to achieve encapsulation with Lua.
Do you happen to have a sample project with that code. Would love to have a working example to play around with.

I see some other links in that post describing that Lua can may also achieve object composition/inheritance. Any good working examples of that as well ?

I’m guessing Lua probably does not support polymorphism.

thanks again.