Say I declare a lua function using the : operator like so:
function ClassName:myFunc( stuff )
--do stuff
end
And then say I store that function in a table like so:
someTable = {
ClassName.myFunc,
someGlobalFunc,
}
And then, say I have another function that goes through the table and attempts to call the given functions.
function ClassName:callStuffInThisTable(table)
-- I go through the table, which might be someTable above, and call all the functions
end
My question is, how do I know if a function in the table is owned by ClassName, so that I can call it using self?
You don't. At least, Lua isn't going to tell you.
function ClassName:myFunc( stuff )
is just syntactic sugar as far as Lua is concerned. It's no different from this: ClassName.myFunc = function (self, stuff)
. The functions are equivalent.
Likewise for the : call syntax, ClassName:myFunc(stuff)
is semantically equivalent to ClassName.myFunc(ClassName, stuff)
.
It is up to you to know what your functions are and what they do. This requires coding discipline. If you have a list of functions that you need to call in a loop, then they should be designed to be called with the same parameters.
There are two ways to do this. One way is to make all of the functions "class functions":
someTable = {
ClassName.myFunc,
function(self, ...) return someGlobalFunc(...) end,
}
This way, the self
parameter is ignored. Obviously, you could create a special function table object that has functions for inserting "global" functions into the table that will automatically generate the wrapper:
function insertFuncIntoTable(self, func)
self[#self + 1] = function(self, ...) func(...) end
end
insertFuncIntoTable(someTable, someGlobalFunc)
Note: there is a difference between these, assuming "someGlobalFunc" is actually a member of the global table (rather than a local
). This version will take the value that _G["someGlobalFunc"]
currently has, just as your original code does. However, the first version takes the value that it has at the time it is called, which may be a different function from the one it was at the time someTable
was created.
So this version is safer.
Alternatively, you can make it so that any "class functions" in the table are explicitly bound to an object instance:
someTable = {
function(self, ...) ClassName.myFunc() end,
function(self, ...) return someGlobalFunc(...) end,
}
BTW, in general, if you declare a function using :
syntax, you're supposed to use that function that way, via instance:myFunc(...)
. Obviously it's just a Lua function like any other, so you can do what you like. But misuse can make understanding what's going on harder.
Lua affords you a lot of power. But you're still required to exercise judgement and discipline when coding. Lua will not save you from yourself (entirely).
Ultimately what I'm trying to do is make a script that iterates through functions and parameters, waiting when necessary, and so I'm doing this:
script = {
{ func, { params } },
}
Ideally though I'd have user functions and pre-implemented functions. I can easily pass a self object, I was just trying to be clever - Charles Randall 2012-04-05 01:11
One way to tell if the function is "owned" by ClassName would be to scan and check.
ClassName = {}
function ClassName:fn(self) ... end
t = { function() ... end , ClassName.fn() }
function has_value( klass, value )
for k,v in pairs(klass) do
if v==value then return true
end
return false
function ClassName:callStuffInThisTable(table)
for k,v in pairs(table) do
if has_value(ClassName, v) then
v(self)
else
v()
end
end
end
This has O(n^2) behaviour though due to the table scan. We can reduce this to O(n log(n)) ) by using the functions in ClassName as a new table
function ClassName:callStuffInThisTable(table)
local t = {}
for k,v in pairs(ClassName) do
t[v] = 1
end
for k,v in pairs(table) do
if t[v]==1 then
v(self)
else
v()
end
end
end