lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



-----Original Message----- 
> From: "Dirk Laurie" <dirk.laurie@gmail.com> 
> To: "Lua mailing list" <lua-l@lists.lua.org> 
> Date: 01-05-2014 21:34 
> Subject: Re: Ideas about colon operator syntax (and a patch in the work) 
> 
> 2014-05-01 19:50 GMT+02:00 Thomas Jericke <tjericke@indel.ch>:
> 
> > I am not so sure if I would implement it this way. Just as a Gedankenexperiment,
> > if methods would be first class citizen of Lua it would mean that the function itself
> > would know that it is a method or a static function.
> >
> > So if you write:
> > table = {}
> > function table:f ()
> >   ....
> > end
> >
> > f would contain a internal reference to table. So local b = table.f would contain that
> > reference as well and b() would call f with table as first parameter.
> 
> That's a totally different paradigm. The colon in Lua is sugar for
> sugar for sugar.
> 
> function table:f (...)
> 
> is sugar for
> 
> function table.f (self,...)
> 
> which is sugar for
> 
> table.f = function(self,...)
> 
> which is sugar for
> 
> table["f"] = function(self,...)
> 
> So f receives a local reference to the object, not a reference to the prototype.

I think I know what the ':' operator does. But thank you for showing me again why it
is a little too sweet for my taste (I like sugar but this is just too much).

But I think you got me wrong. A first class method would not store a reference to
the prototype (a Lua function already does that). It would store a reference to its object.

There are already two ways to archive this. A function can either store a reference to its object
in the closure, or you can use a table/userdata to implement a method and setting the __call operator
to call the function.

Those two ways of implementing OOP in Lua share a lot:
They come at a price (Closures/Metatable-lookups), they make it possible to hide the data from the
user and only make the methods accessible. And they don't need the ':' operator to use them.

There is another interesting feature of this kind of OOP implementation that I
used to map our module framework.

In out automation framework we have 'modules' that have submodules, properties and commands.
To avoid naming conflicts they are stored in folders and folders are defined by '.' in the names.
So instead of 'obj.funct' we defined 'obj.cmd.funct' and 'obj.module.submodule', 'obj.prop.simulate'

Now I can't use the colon operator as 'obj.cmd:funct(1)' would be 'obj.cmd.funct(cmd, 1)' but I
want obj.cmd.funct(obj, 1). Anyway my solution was simple, obj.cmd.funct is a userdata that has a __call in
its metatable that does the call, and it has all the information stored in the userdata that it needs.
--
Thomas