Add code to existing functions

Hello everyone,

As a title I would like to add code to an already created feature.

This is an example of my test code:

--------------------- ------main.lua------- --------------------- local ball = require("ball") local newObj = ball.new() newObj.finalize = function() print("Second finalize") end newObj:addEventListener( "finalize" ) display.remove(newObj) --------------------- ------ball.lua------- --------------------- local M = {} function M.new() local obj = display.newCircle( 160, 250, 30 ) obj:setFillColor( 1, 0, 0 ) function obj:finalize() print("First finalize") end obj:addEventListener( "finalize" ) return obj end return M

Of course the code printed twice “Second finalize”. As the second method overwrites the first one

Is there a way to make the methods “found” instead of “overwhelming”?

I know that I can call functions with different names and apply the finalize event to both.

But I’m interested in knowing if there is a way to fond them

local newObj = ball.new() newObj.firstFinalize = newObj.finalize -- store it newObj.finalize = function(self) self:firstFinalize() -- call it print("Second finalize") end -- newObj:addEventListener( "finalize" ) -- no need

Good idea this works. I had also thought of something like that.

But I ask myself something.  If I did not know if the first event is a function created with “.” or “:”?

There is a way to solve this?

a table listener is always called using equivalent of “:” (ie, passing ‘self’ param)

I’m not following you.

I can do it:

 function obj:finalize() --code here end obj:addEventListener( "finalize" )

or

 obj.finalize = function() --code here end obj:addEventListener( "finalize" )

so then I have to know here if I use “.” or “:” otherwise I get a mistake

local newObj = ball.new() newObj.firstFinalize = newObj.finalize -- store it newObj.finalize = function(self) self:firstFinalize() --\<=== at this point "." or ":" print("Second finalize") end -- newObj:addEventListener( "finalize" ) -- no need

first, understand that the following two snippets are functionally identical:

t = {} function t:f() end -- implicitly declares 'self' as first param t:f() -- implicitly passes 't' itself as first param

t = {} function t.f(self) end -- explicitly declare 'self' as first param t.f(t) -- explicitly passes 't' itself as first param

it simply doesn’t matter what form you use, you can even call a “:” declared function with the t.f(t) syntax, but the common convention is to use the provided “:” syntactic sugar whenever ‘self’ is involved.

…because (again) Corona always calls a table-based listener with a ‘self’.  so “finalize()” is going to be called equivalent to newObj:finalize() or newObj.finalize(newObj) - the first argument to the function WILL be the ‘self’ reference.

your ORIGINAL finalize (in the ball class) should ALSO be declared such that it has a ‘self’ parameter, if you ever want to access it.

however, there is nothing preventing you from doing something like the following:

t = display.newWhatever(... t.finalize = function() end -- note there will be no self parameter t.addEventListener("finalize") -- the listener will be called as:&nbsp; t:finalize(), so a 'self' WILL be passed -- BUT you'll have no 'self' parameter to actually ACCESS it within the function -- everything will seem to work unless/until you try to actually USE 'self'

in short, you can make it as “weird” as you want, or just follow the convention and use “:” throughout - then you won’t have to go hunting through your code to figure out weird errors like “attempt to index ‘self’ (a nil value)” if you neglect to either call with a “:” or pass the table itself when called with a “.”

Thank you for the explanation.

What you said makes sense. Finalize it would be better to create it with “:” for the reasons you stated above.

So your initial solution is fine. Nevertheless, give me a last question. I would like to know if there is a way to know if the created feature was created with “.” or “:”. Not in this case. But I think it’s necessary in some cases to know it. Is there a way to know this? If I ask too much I apologize

nope, no such “introspective” tools available from the runtime - lua doesn’t care that the number of declared parameters matches the number of passed parameters, so it sort of doesn’t think you need to know this.  (the compiler knows, but not the runtime)   you could try the debug library, but you really shouldn’t need to - just consult your own source code and call as appropriate.

why? as far as your code can see at runtime, all of the following functions would have an identical “signature” (set of params):

t = {} function t:a() end -- has one param, implicity named 'self' function t.b(self) end -- has one param, explicitly named 'self' function t.c(notself) end -- has one param, explicitly named 'notself' (Q: is this an object.method, or not?)

note that it would be perfectly legal to call t:c() in object.method style (though ‘inside’ that function you’d have to use ‘notself’ instead of ‘self’ to get the object reference - some c++/java/javascript converts do this intentionally to rename it as ‘this’)

May I ask why you want to know if the first finalize was defined in the module ball?  Just curious.  If doesn’t seem like you should really need to know this but you might have a good reason.  

In any case, you should look into the setmetatable function.   I am no expert but it is my understanding that when you include a module from something else those functions are listed in the metatable of your table.   Not your main table.  The metatable is referenced by __index.   When you reference finalize lua looks in your main table for the name.  If it isn’t found then is searches your metatable for the name.  If it finds it there then it uses that one.  So I would assume you could search the metatabble first and see if there and then you would have your question answered.   You could then run which ever one you want.   

--------------------- ------ball.lua------- --------------------- local M = {} local M_mt = { __index = M } function M:new() local obj = display.newCircle( 160, 250, 30 ) obj:setFillColor( 1, 0, 0 ) setmetatable( obj , M_mt ) return obj end function M:finalize() print(“First finalize”) return end function M:addlistener() self:addEventListener( “finalize” , self ) return end return M

Maybe something like that.  

altering the metatable of a Corona display object is more complicated than that - i would not recommend given OP’s apparent experience level

@davebollinger

Thanks a lot! I understand it is very early, even more than I thought

@laurasweet8888

I do not think that’s what I need.What you have proposed, I think, is long and complex.

To answer your question “why you want to know if the first finalize was defined in the module ball”: 

finalize it was just an example. The thing I need is to know, in a “quick” way, a function has been created with “.” or “:”.

Very often it happens that we use non-proprietary libraries or parts of code.

So I make a “stupid” example, I hope to make the idea:

My code:

-------- --ball-- -------- local M = {} function M.new() local obj = display.newCircle( 160, 250, 30 ) obj:setFillColor( 1, 0, 0 ) function obj:finalize() print("First finalize") end obj:addEventListener( "finalize" ) return obj end return M

external code:

------------------- --otherBall.lua-- ------------------- local M = {} function M.new() local obj = display.newCircle( 160, 250, 30 ) obj:setFillColor( 1, 0, 0 ) obj.finalize = function() print("First finalize other ball") end obj:addEventListener( "finalize" ) return obj end return M

in the my main

------------ --main.lua-- ------------ local ball = require("ball") local obj\_1 = ball.new() obj\_1.firstFinalize = obj\_1.finalize -- store it obj\_1.finalize = function(self) self:firstFinalize() -- call it print("Second finalize") end display.remove(obj\_1) local otherBall = require("otherBall") local obj\_2 = otherBall.new() obj\_2.firstFinalize = obj\_2.finalize -- store it obj\_2.finalize = function(self) self:firstFinalize() -- call it print("Second finalize") end display.remove(obj\_2)

In this example the finalize on the second object will not work and will give error.

I know that it would be enough to standardize the module “otherBall”.

But I’m fascinated by the idea of finding a solution that would automatically know if the object had a function. “” or “:” and acted accordingly.

I hope I explained. I’m not native speaker…

I get it now.  Didn’t mean to lead you down the wrong path.  

local newObj = ball.new() newObj.firstFinalize = newObj.finalize -- store it newObj.finalize = function(self) self:firstFinalize() -- call it print("Second finalize") end -- newObj:addEventListener( "finalize" ) -- no need

Good idea this works. I had also thought of something like that.

But I ask myself something.  If I did not know if the first event is a function created with “.” or “:”?

There is a way to solve this?

a table listener is always called using equivalent of “:” (ie, passing ‘self’ param)

I’m not following you.

I can do it:

 function obj:finalize() --code here end obj:addEventListener( "finalize" )

or

 obj.finalize = function() --code here end obj:addEventListener( "finalize" )

so then I have to know here if I use “.” or “:” otherwise I get a mistake

local newObj = ball.new() newObj.firstFinalize = newObj.finalize -- store it newObj.finalize = function(self) self:firstFinalize() --\<=== at this point "." or ":" print("Second finalize") end -- newObj:addEventListener( "finalize" ) -- no need

first, understand that the following two snippets are functionally identical:

t = {} function t:f() end -- implicitly declares 'self' as first param t:f() -- implicitly passes 't' itself as first param

t = {} function t.f(self) end -- explicitly declare 'self' as first param t.f(t) -- explicitly passes 't' itself as first param

it simply doesn’t matter what form you use, you can even call a “:” declared function with the t.f(t) syntax, but the common convention is to use the provided “:” syntactic sugar whenever ‘self’ is involved.

…because (again) Corona always calls a table-based listener with a ‘self’.  so “finalize()” is going to be called equivalent to newObj:finalize() or newObj.finalize(newObj) - the first argument to the function WILL be the ‘self’ reference.

your ORIGINAL finalize (in the ball class) should ALSO be declared such that it has a ‘self’ parameter, if you ever want to access it.

however, there is nothing preventing you from doing something like the following:

t = display.newWhatever(... t.finalize = function() end -- note there will be no self parameter t.addEventListener("finalize") -- the listener will be called as:&nbsp; t:finalize(), so a 'self' WILL be passed -- BUT you'll have no 'self' parameter to actually ACCESS it within the function -- everything will seem to work unless/until you try to actually USE 'self'

in short, you can make it as “weird” as you want, or just follow the convention and use “:” throughout - then you won’t have to go hunting through your code to figure out weird errors like “attempt to index ‘self’ (a nil value)” if you neglect to either call with a “:” or pass the table itself when called with a “.”

Thank you for the explanation.

What you said makes sense. Finalize it would be better to create it with “:” for the reasons you stated above.

So your initial solution is fine. Nevertheless, give me a last question. I would like to know if there is a way to know if the created feature was created with “.” or “:”. Not in this case. But I think it’s necessary in some cases to know it. Is there a way to know this? If I ask too much I apologize

nope, no such “introspective” tools available from the runtime - lua doesn’t care that the number of declared parameters matches the number of passed parameters, so it sort of doesn’t think you need to know this.  (the compiler knows, but not the runtime)   you could try the debug library, but you really shouldn’t need to - just consult your own source code and call as appropriate.

why? as far as your code can see at runtime, all of the following functions would have an identical “signature” (set of params):

t = {} function t:a() end -- has one param, implicity named 'self' function t.b(self) end -- has one param, explicitly named 'self' function t.c(notself) end -- has one param, explicitly named 'notself' (Q: is this an object.method, or not?)

note that it would be perfectly legal to call t:c() in object.method style (though ‘inside’ that function you’d have to use ‘notself’ instead of ‘self’ to get the object reference - some c++/java/javascript converts do this intentionally to rename it as ‘this’)

May I ask why you want to know if the first finalize was defined in the module ball?  Just curious.  If doesn’t seem like you should really need to know this but you might have a good reason.  

In any case, you should look into the setmetatable function.   I am no expert but it is my understanding that when you include a module from something else those functions are listed in the metatable of your table.   Not your main table.  The metatable is referenced by __index.   When you reference finalize lua looks in your main table for the name.  If it isn’t found then is searches your metatable for the name.  If it finds it there then it uses that one.  So I would assume you could search the metatabble first and see if there and then you would have your question answered.   You could then run which ever one you want.   

--------------------- ------ball.lua------- --------------------- local M = {} local M_mt = { __index = M } function M:new() local obj = display.newCircle( 160, 250, 30 ) obj:setFillColor( 1, 0, 0 ) setmetatable( obj , M_mt ) return obj end function M:finalize() print(“First finalize”) return end function M:addlistener() self:addEventListener( “finalize” , self ) return end return M

Maybe something like that.