I’ve never been a big fan of Object Oriented Programming. Maybe in part due to the fact that my first introduction to it was C++, which I despised. Was happy with C. Then I fell in love with functional languages and saw even less need for objects to complete most tasks. I’ll give the OO crowd that some problems do make sense to have objects. But calm down. I hate hearing language A has no OOP support, blah blah blah, when in fact it does, just not your fancy keyword ‘class’ style OOP. C is an example of that, look at the VFS code in the Linux kernel. And far better than C’s, Lua and Erlang’s impressed me with their versions of objects.
Lua is a tiny functional language based around a single data structure, the table. The flexibility is amazing. After writing just a little code to deal with passing messages from C to Lua and calling all functions registered to receive that call in Lua I was hooked. Classes in Lua can be built with just tables, still allowing for single and multiple inheritance and privacy. Below is code to create class in Lua:
Account = {balance=0}
function Account:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end
function Account:withdraw(v)
self.balance = self.balance – v
end
The first line creates a table Account with variable balance. Next, a function is defined to live in Account. The ‘new’ function accepts a table and makes self, Account, the metatable for o. Lastly, set __index to self, Account, as well and return the table o. Now we can create a new object and use the Account methods and variables:
a = Account:new{balance = 10}
a:withdraw(5)
print(a.balance)
The above passes the table {balance=10} to new, overwriting balance=0. Now the sexy part happens. a tries to call withdraw, but has no withdraw element in it’s table. When Lua tries to find something in a table and it is missing it checks if it has a metatable and if that has __index defined. If so it then goes to the table __index points to and searches for the element. In this example it goes to the Account table and finds withdraw, the withdraw call basically turns into:
Account.withdraw(a, 5)
Objects! Woooo. Ok, so there is a little of syntatic sugar. My favorite is all the fun things you can do with tables and metatables besides objects, but are close to objects. Things that in another language you would have to create a whole new object in order to do. Those are for another day.
This was going to delve into Erlang OOP as well, but is already too long. That will be my next post. I’d like to leave on another funky thing you can do with metatables in Lua. Almost, everything uses tables in Lua, even arithmetic. You can create a metatable to define __add and redefine the + op. I know you can do that in other languages, but it shows how you can do anything and everything with Lua and tables, and Lua is an EXTREMELY small lanaguage. But oh so powerful.
This code was taken from Programming in Lua, Second Edition and adapted to meet my needs for this post.