lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]



On 16/11/14 05:19 PM, jseb wrote:
   Take a look at package.loaded.  Not only does it contain a
reference to package, but it also contains a reference to _G.
Ah yes, just saw that.

And there were problem also in the searching loop: when found, the
search continues and it ends with returning nil. Each returning
call should test if there were some success previously.

Correct version:

function _get_fx_name(fx, t)
   local ret = nil
   for k,v in pairs(t) do
     if fx == v then
       print("found", k,v)
       return k
     end
     if type(v) == "table" and k ~= "_G"  and k ~= "package" then
       ret = _get_fx_name(fx, v)
       if ret then goto exit end
     end
   end
::exit::
   return ret
end

function get_fx_name(fx)
   local name
   name = _get_fx_name(fx, _ENV)
   name = name or "unknown function"
   return name
end


I know it's pretty not pretty, but that's the most i can do.


Use this: (just remember to modify get_fx_name with your name-picking algorithm)

Features: if _ENV has a t={} t[t]=t, it doesn't lock up.

local function scan(_table, _type, _callback, _userdata)
  local todo = {[_table] = true}
  local seen = {}
  local path = {}
  -- we can't use pairs() here because we modify todo
  while next(todo) do
    local t = next(todo)
    todo[t] = nil
    seen[t] = true
    for k, v in next, t do
      if type(v) == _type then
        _callback(t, k, v, _userdata)
      end
      if not seen[k] and type(k) == "table" then
        todo[k] = true
      end
      if not seen[v] and type(v) == "table" then
        todo[v] = true
      end
    end
  end
end

local function check_fx(t, k, v, userdata)
  if v == userdata.fx then
    table.insert(userdata.names, k)
  end
end

function get_fx_name(fx)
  local names = {}
scan(_ENV, "function", check_fx, {names = names, fx = fx}) -- avoid making new closures
  -- pick a name from names
  return name or "unknown function"
end