First off, increpare, you got those backwards! The colon : is syntax sugar, with
a:b() being shorthand for
a.b(a).
Next, as checking for a global is a table lookup, if you look for
'something.whatever', it is going to try to
rawget(_G, 'something.whatever') which will fail (
_G['something'] is a table,
_G['something']['whatever'] is a function, but
_G['something.whatever'] is nil)
In order to check if
something.whatever exists by string, you'd need to tokenize on
'.' and do table lookup for each piece individually. So
'a.b.c.d.e.f', would search
_G for
'a', then with a on the stack, look for
'b' inside of that, then with b on the stack, look for
'c', and so on.
But, I recommend a better solution. First why do you need even to check existence? I'm assuming this is because you want to check if something 'exists' because you're actually referencing this data later in C code and invoking it or something. This is okay, but don't use strings for this purpose. Bad idea.
If the object is
nil, it does not exist (any undefined variable is
nil), see
lua_isnil. Also you can verify Lua value types in C code. The Lua auxiliary library can help you with certain parts of the type checking, like
luaL_checkudata. The other parts can be done through various
lua_is*(...) checks or by
lua_type. You don't need a function_exists helper.
If you need to keep a persistent reference to this data in C which lasts beyond whatever initial call needs this function, you still don't want strings. Instead have them pass their Lua object directly to your C functions, and use the Lua registry (special table located at the stack pseudoindex
LUA_REGISTRYINDEX) to store any references you need to keep. See
luaL_ref for storing registry entries,
luaL_unref for removing them, and
lua_rawgeti for retreiving that data back later.
Otherwise, there is no point in coding functions to do an existence check. Inside Lua scripts, the user can already very easily just check with a simple
if my.magical.var.from.outer.space then ... end block to see if something exist (since if statements consider both
false and
nil as logically false, and any other values as logically true). If you need to check explicitly for type in Lua code, there's bad design somewhere, but you can do
type(expr) and get a string for what type a value is.
Hope this helps.
EDIT:
I suppose since there are rare cases you actually want to do this for other purposes, here's a Lua implementation of functionExists:
helper = {}
function helper.resolveName(name)
local a = _G
for key in string.gmatch(name, "([^%.]+)(%.?)") do
print(key)
if a[key] then
a = a[key]
else
return nil
end
end
return a
end
function helper.functionExists(name)
return type(helper.resolveName(name)) == 'function'
end