Lua does not have build in support for OO, but it allows you to build it yourself. Could you please share some of the ways one can implement OO?
Please write one example per answer. If you have more examples, post another answer.
Although Lua does not have a built-in concept of classes, object-oriented programming can be emulated using functions and tables. An object is formed by putting methods and fields in a table.
The only difference is in Lua you can do it in many different ways, but you can do object oriented programming in Lua, so Lua is OOP." The pragmatists then go on to say Lua gives you ways that *you* can construct things that act like OOP in other languages.
Objects are designed to share behaviors and they can take on more than one form. The program will determine which meaning or usage is necessary for each execution of that object from a parent class, reducing the need to duplicate code. A child class is then created, which extends the functionality of the parent class.
There are three major pillars on which object-oriented programming relies: encapsulation, inheritance, and polymorphism.
I like to think of OOP as being the encapsulation of data inside a container (the Object) coupled with a subset of operations that can be done with this data. There IS a lot more to it, but let's assume that this simple definition is all and build something in Lua from it (also some familiarity with other OO implementations can be a nice boost for the reader).
As anyone with a little exposure to Lua may know, tables are a neat way to store key-value pairs and in combination with strings, things start to become very interesting:
local obj = {} -- a new table obj["name"] = "John" obj["age"] = 20 -- but there's a shortcut! print("A person: " .. obj.name .. " of the age " .. obj.age)
String values as keys in a table can be accessed in a way very alike to the members of a struct in C or the public members of an object in C++/Java and similar languages.
And now for a cool magic trick: let's combine this with anonymous functions.
-- assume the obj from last example obj.hello = function () print("Hello!") end obj.goodbye = function () print("I must be going.") end obj.hello() obj.goodbye()
Awesome right? We now have means of having functions stored inside our tables, and again you can see it resembles how methods are used in other OOP languages. But something is missing. How can we access the data that belongs to our object inside our method definitions? This is generally addressed by changing the signature of the functions in the table to something like this:
-- assume the obj from last example obj.inspect = function (self) print("A person: " .. self.name .. " of the age " .. self.age) end obj.hello = function (self) print(self.name .. ": Hello! I'm " .. self.name) end obj.goodbye = function (self) print(self.name .. ": I must be going.") end -- now it receives the calling object as the first parameter obj.inspect(obj) -- A person: John of age 20 obj.hello(obj) -- John: Hello! I'm John obj.goodbye(obj) -- John: I must be going
That solves it in a simple manner. Maybe drawing a parallel to the way things work in Python (methods always get a explicit self) can aid you in learning how this works in Lua. But boy, isn't it inconvenient to be passing all these objects explicitly in our method calls? Yeah it bothers me too, so there's another shortcut to aid you in the use of OOP:
obj:hello() -- is the same as obj.hello(obj)
Finally, I have just scratched the surface of how this can be done. As has been noted in Kevin Vermeer's comment, the Lua Users Wiki is an excellent source of information about this topic and there you can learn all about how to implement another important aspects of OOP that have been neglected in this answer (private members, how to construct objects, inheritance, ...). Have in mind that this way of doing things is a little part of the Lua philosophy, giving you simple orthogonal tools capable of building more advanced constructs.
For a quick and dirty oo implementation I do something like -
function newRGB(r,g,b) return { red=r; green=g; blue=b; name=''; setName = function(self,name) self.name=name; end; getName = function(self) return self.name; end; tostring = function(self) return self.name..' = {'..self.red..','..self.green..','..self.blue..'}' end } end
which can then be used like -
blue = newRGB(0,0,255); blue:setName('blue'); yellow = newRGB(255,255,0); yellow:setName('yellow'); print(yellow:tostring()); print(blue:tostring());
for a more full featured approach I would use an oo library as was mentioned by eemrevnivek. You can also find a simple class function here which is somewhere between full on library and quick and dirty.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With