On Mar 4, 2017, at 10:13 AM, Sean Conner <sean@conman.org> wrote:
I use the OOP syntactic surgar for my userdata to isolate the functions
that work on a particular type to just that type. For example, my socket
class [1], I have functions that create sockets [2]:
Looks good to me! I'm not saying that OOP is always bad. The original post is about extending the existing ':' notation for a more complex case (composition), and I was trying to point out that there are probably simpler solutions to get things done. In my experience, with OOP it's very easy to over-engineer problems, or get distracted by form at the cost of functionality (been there, done that!).
Also, I'm not polluting the
global namespace, or the socket namespace, with functions that require a
particular userdata to do their job.
Also an API made of free functions doesn't have to be in global namespace. The usual solution of require returning a table of public functions of a module works just fine.
Another advantage of the imperative style:
-- OOP
for i=1,#objs do
objs[i]:do_something()
end
function myclass:do_something()
-- code here
end
Again, if the objs are subtly different there could be different
implementations of do_something(). For instance, the objects could be
sockets, where you have one socket for accepting new connections and several
other sockets that are ongoing connections so the code for do_something()
would be different.
In that case I would usually just make two different functions, or pass two arrays into do_something if it makes sense. Better to know the types of objects you are working with and make program flow explicit.
Petri