Safely create member functions in Lua
At first there was the simple syntax, and developers could use object.property = "value" to assign or val = object.property to get the value, and with functions there was object.function() to invoke a function that was a member of the object. Pure simple and easy.
Then developers saw, there were some functions that had a : instead of a . and that confused them, what is that, whey are there :'s in some places and .'s in some. This is way too confusing, but nevertheless, the API Documentation suggests that certain functions are to be used with a . and some with a : so they were used without any questions.
As this progressed, developers learned that modules can be used, and with modules came the module(..., package.seeall) after a little while, say about 6 months or so, this was the wrong way to deal with things. So if you make modules you should not use the module(...,package.seeall) declaration.
Anyways, with all of that evolution, one things remained and it never got clarified, where is the . and the : used? Most importantly, how can we ensure that this will work perfectly fine irrespective of the way it is defined or called?
here's an example
and in our main.lua file, we can
this should work, but there are times when a developer might actually have forgotten that the function was defined with a . and is called with a :, so this will not work and cause an error.
In English, we say "cut the wood with an axe" and if we had a compound sentence, we would say "Take an axe and cut the wood with it" Now most that have studied, known English will know that in the second sentence we imply the Axe as it, even though we are not saying specifically. similarly, in code terms,
but we could have the code as
so we have axe as an object that has a member function chop, so we can call it and chop wood (the type we pass to it)
but then some developer comes along and tries axe:chop(wood), what happens now?
The first example, where we called axe.chop is similar to "cut wood with an axe"
and the second example is similar to "take an axe, and cut wood with it"
so when we call the axe:chop, it passes a reference of itself to the function as the first parameter, which is not defined on the function declaration, so what happens is that
axe.chop(wood)
wood becomes the axe when called with axe:chop and there is no wood.
If you or the developers that will use your code be dwindling between using the axe.chop and axe:chop, it is best to define the function (as a general rule for yourself) as
now what it does is it caters for that extra variable that is implicitly passed, if you were developing with Obj-C, or other languages, you would realise that generally the declaration is defined as
so it is best to keep that and now there is one difference, all calls to axe:chop(wood) will work however you will have to call the axe.chop method as axe.chop(axe,wood) slightly redundant, but worth the effort and you will not face errors due to the . and : again.
Then developers saw, there were some functions that had a : instead of a . and that confused them, what is that, whey are there :'s in some places and .'s in some. This is way too confusing, but nevertheless, the API Documentation suggests that certain functions are to be used with a . and some with a : so they were used without any questions.
As this progressed, developers learned that modules can be used, and with modules came the module(..., package.seeall) after a little while, say about 6 months or so, this was the wrong way to deal with things. So if you make modules you should not use the module(...,package.seeall) declaration.
Anyways, with all of that evolution, one things remained and it never got clarified, where is the . and the : used? Most importantly, how can we ensure that this will work perfectly fine irrespective of the way it is defined or called?
here's an example
--module.lua local module={} function module.multiply(a,b) return a*b end return module
and in our main.lua file, we can
local mod = require("module") print(mod:multiply(2,4))
this should work, but there are times when a developer might actually have forgotten that the function was defined with a . and is called with a :, so this will not work and cause an error.
First, what's what
What is a . and what is a :In English, we say "cut the wood with an axe" and if we had a compound sentence, we would say "Take an axe and cut the wood with it" Now most that have studied, known English will know that in the second sentence we imply the Axe as it, even though we are not saying specifically. similarly, in code terms,
local chop(wood,axe) print("Cutting ", wood, " with ", axe) end
but we could have the code as
local axe={} function axe.chop(wood) print("chopping ", wood, " with this axe") end
so we have axe as an object that has a member function chop, so we can call it and chop wood (the type we pass to it)
but then some developer comes along and tries axe:chop(wood), what happens now?
The first example, where we called axe.chop is similar to "cut wood with an axe"
and the second example is similar to "take an axe, and cut wood with it"
so when we call the axe:chop, it passes a reference of itself to the function as the first parameter, which is not defined on the function declaration, so what happens is that
axe.chop(wood)
wood becomes the axe when called with axe:chop and there is no wood.
Hopefully, you have gotten this far
Now the point is how to make it safe,If you or the developers that will use your code be dwindling between using the axe.chop and axe:chop, it is best to define the function (as a general rule for yourself) as
local axe = {} function axe.chop(self,wood) end
now what it does is it caters for that extra variable that is implicitly passed, if you were developing with Obj-C, or other languages, you would realise that generally the declaration is defined as
- (void) chop:(id)sender;
so it is best to keep that and now there is one difference, all calls to axe:chop(wood) will work however you will have to call the axe.chop method as axe.chop(axe,wood) slightly redundant, but worth the effort and you will not face errors due to the . and : again.
Woow,believe or not I was thinking about this couple days ago...
ReplyDeleteI like it:)