Question with redefining colon function using dot

Hey.

So I’ve been somewhat experimenting with the lua language recently and I came across a discovery/issue i’ve wanted to find the answer to if this is right

local object = {} local storedFunct = {} local function removeFunctions(table) table.save = nil table.add = nil end local function addFunctions(table) table.save = storedFunct.save table.add = storedFunct.add end function object:save() removeFunctions(self) --- call a function that saves the self without functions addFunctions(self) end function object:add() removeFunctions(self) -- do something addFunctions(self) end storedFunct.save = object.save storedFunct.add = object.add return object

local myobject = require(“test”)
 

So say I called myobject:save()

That would remove the colon( : ) and dot( . ) functions from myobject self

Save to the file (do whatever) without the functions the myobject, then reattach the functions

I am still able to use myobject:save() using self even though I’ve reattached the save function using dot( . )

Basically I want to know why this works, and if there would be a cleaner/simpler way (without using metatables)

thanks so much.
brian

Note: dot (.) and colon ( : ) are purely syntactical sugar.  As well, ‘self’ is not a reserved word or magic in any way.

These are all equivalent:

local tmp = {} tmp.age = 10 function tmp.doit1( self, name) print( name, " is ", self.age ) end function tmp.doit2( obj, msg ) print( name, " is ", obj.age ) end function tmp:doit2( msg ) -- Implies an argument referencing object named 'self' as first arg. print( name, " is ", self.age ) end

Then called in any of these ways:

tmp:doit1( "Bobby" ) tmp.doit1( tmp, "Bobby" ) tmp:doit2( "Bobby" ) tmp.doit2( tmp, "Bobby" ) tmp:doit3( "Bobby" ) tmp.doit3( tmp, "Bobby" ) 

There was a wonderful blog post here on the site covering this topic just recently: 

https://coronalabs.com/blog/2015/12/01/tutorial-understanding-the-colon-vs-dot-operator/

PS - Extra Credit

Guess what this will do if added after the above code:

local tmp2 = {} tmp2.age = 12 tmp.doit1( tmp2, "Buddy" )

Hi again:

In your example:

storedFunct.save = object.save storedFunct.add = object.add

object.save and object.add are just references to functions.  In no way are these uniquely tied to ‘object’.  So, you can just assign them to another object and they will will just fine.

Consider this:

local tmp1 = { age = 10 } local tmp2 = { age = 12 } local tmp3 = { age = 100000 } local function doit( self, name ) print( name, " is ", self.age ) end tmp1.showAge = doit -- variable points to doit() tmp2.showAge = doit -- variable points to doit() tmp3.showAge = tmp1.showAge -- variable points to doit() tmp1:showAge("Billy") tmp2:showAge("Bobby") tmp3:showAge("Susy")

Note: You absolutely DO NOT need to dig into metatables for this kind of programming. 

Fascinating, 

Yeah, I glanced at the article a few days ago which triggered the exploration of messing around with the dot and colon operators on my code.  

I have thought that I had to define the object with : initially in order to be treated as one that referenced self, but your examples helped clean up that assumption.  I could assign it with a . notation, add the first param as ‘self’ and call it via : to satisfy the first parameter.

I also just looked at the “careful” part and it further made me understand the logic behind it.

buddy is 12 should be that answer btw.

thank you for the detailed response

Just as a side note, I would advise you to not use variables or args with names that are already used by Lua/Corona such as “table”.

In your example it shouldn’t cause any errors, but it would be very easy to run into problems if you call a variable “table” since you’ll be overwriting the existing table functionality. The same goes for things such as “string”, “Runtime” and “system”.   

I once had an error that took me forever to fix because I had a lua file called “credits” or something along those lines, and at the time Corona had it’s own file with the same name. The error didn’t say that I’d overwritten an existing file, it simply failed to implement “credits” the way that Corona was expecting to so I was seeing errors that were completely baffling.

Note: dot (.) and colon ( : ) are purely syntactical sugar.  As well, ‘self’ is not a reserved word or magic in any way.

These are all equivalent:

local tmp = {} tmp.age = 10 function tmp.doit1( self, name) print( name, " is ", self.age ) end function tmp.doit2( obj, msg ) print( name, " is ", obj.age ) end function tmp:doit2( msg ) -- Implies an argument referencing object named 'self' as first arg. print( name, " is ", self.age ) end

Then called in any of these ways:

tmp:doit1( "Bobby" ) tmp.doit1( tmp, "Bobby" ) tmp:doit2( "Bobby" ) tmp.doit2( tmp, "Bobby" ) tmp:doit3( "Bobby" ) tmp.doit3( tmp, "Bobby" ) 

There was a wonderful blog post here on the site covering this topic just recently: 

https://coronalabs.com/blog/2015/12/01/tutorial-understanding-the-colon-vs-dot-operator/

PS - Extra Credit

Guess what this will do if added after the above code:

local tmp2 = {} tmp2.age = 12 tmp.doit1( tmp2, "Buddy" )

Hi again:

In your example:

storedFunct.save = object.save storedFunct.add = object.add

object.save and object.add are just references to functions.  In no way are these uniquely tied to ‘object’.  So, you can just assign them to another object and they will will just fine.

Consider this:

local tmp1 = { age = 10 } local tmp2 = { age = 12 } local tmp3 = { age = 100000 } local function doit( self, name ) print( name, " is ", self.age ) end tmp1.showAge = doit -- variable points to doit() tmp2.showAge = doit -- variable points to doit() tmp3.showAge = tmp1.showAge -- variable points to doit() tmp1:showAge("Billy") tmp2:showAge("Bobby") tmp3:showAge("Susy")

Note: You absolutely DO NOT need to dig into metatables for this kind of programming. 

Fascinating, 

Yeah, I glanced at the article a few days ago which triggered the exploration of messing around with the dot and colon operators on my code.  

I have thought that I had to define the object with : initially in order to be treated as one that referenced self, but your examples helped clean up that assumption.  I could assign it with a . notation, add the first param as ‘self’ and call it via : to satisfy the first parameter.

I also just looked at the “careful” part and it further made me understand the logic behind it.

buddy is 12 should be that answer btw.

thank you for the detailed response

Just as a side note, I would advise you to not use variables or args with names that are already used by Lua/Corona such as “table”.

In your example it shouldn’t cause any errors, but it would be very easy to run into problems if you call a variable “table” since you’ll be overwriting the existing table functionality. The same goes for things such as “string”, “Runtime” and “system”.   

I once had an error that took me forever to fix because I had a lua file called “credits” or something along those lines, and at the time Corona had it’s own file with the same name. The error didn’t say that I’d overwritten an existing file, it simply failed to implement “credits” the way that Corona was expecting to so I was seeing errors that were completely baffling.