首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >获取lua中函数的参数名称

获取lua中函数的参数名称
EN

Stack Overflow用户
提问于 2012-05-05 02:25:26
回答 6查看 5.8K关注 0票数 4

当调用lua函数时,如

PrintMe(MyVariableName)

我希望能够真正打印"MyVariableName“而不是它的价值(嗯,为了演示目的)。

显然,我可以传递字符串,但这需要额外的引号,我也想打印它的值。

例如,

代码语言:javascript
运行
复制
MyVariable = 4
PrintVariable(MyVariable)

会打印"MyVariable is 4“之类的

我不想重复名称和变量,比如

代码语言:javascript
运行
复制
PrintVariable(MyVariable, "MyVariable")

因为这是不必要的重复。

卢阿能处理吗?

我现在要做的是在引号中传递变量名,并使用loadstring来获取值,但是我想直接传递变量,而不需要额外的不必要的引号(我认为debug.getlocal这样做了,但最终返回的是值而不是名称)。

下面是模拟示例

代码语言:javascript
运行
复制
function printme1(var, val)
    print(var.." = "..val)
end

function printme2(v)
    local r
    loadstring("r = "..v)() -- equivalent to r = a but must be used since v is a string representing a and not the object a
    print(v.." = "..tostring(r))
end

function printme3(v)
    -- unknown
end

a = 3

printme1("a", a)
printme2("a")
printme3(a) 

在这种情况下,所有三个应该打印相同的东西。printme3显然是最方便的。

EN

回答 6

Stack Overflow用户

发布于 2012-05-05 05:24:10

不能说是PrintVariable(MyVariable),因为Lua无法确定使用哪个变量(如果有的话;可以使用常量)将参数传递给您的函数。但是,您可以说,PrintVariable('MyVariable')然后使用调试API在调用者的作用域中查找具有该名称的局部变量:

代码语言:javascript
运行
复制
function PrintVariable(name)
  -- default to showing the global with that name, if any
  local value = _G[name]

  -- see if we can find a local in the caller's scope with that name
  for i=1,math.huge do
    local localname, localvalue = debug.getlocal(2,i,1)
    if not localname then
      break -- no more locals to check
    elseif localname == name then
      value = localvalue
    end
  end

  if value then
    print(string.format("%s = %s", name, tostring(value)))
  else
    print(string.format("No variable named '%s' found.", name))
  end
end

现在你可以说:

代码语言:javascript
运行
复制
PrintVariable('MyVariable')

在本例中,将打印"MyVariable = 4“。

不是,如果您真的想在没有引号的情况下这样做,您可以检查调用者的局部变量是否有提供的值,但如果调用者的作用域中有多个变量具有给定的值,这偶尔会给出一个错误的变量名。这么说吧,你怎么做到的:

代码语言:javascript
运行
复制
function PrintVariable(value)
  local name

  -- see if we can find a local in the caller's scope with the given value
  for i=1,math.huge do
    local localname, localvalue = debug.getlocal(2,i,1)
    if not localname then
      break
    elseif localvalue == value then
      name = localname
    end
  end

  -- if we couldn't find a local, check globals
  if not name then
    for globalname, globalvalue in pairs(_G) do
      if globalvalue == value then
        name = globalname
      end
    end
  end

  if name then
    print(string.format("%s = %s", name, tostring(value)))
  else
    print(string.format("No variable found for the value '%s'.", tostring(value)))
  end
end

现在您可以说是PrintVariable(MyVariable)了,但是如果调用者的作用域中碰巧有另一个变量4值,并且发生在MyVariable之前,那么就会打印变量名。

票数 5
EN

Stack Overflow用户

发布于 2012-05-05 04:01:14

我有个坏消息我的朋友。您可以访问函数参数名,因为它们出现在函数的顶部,但是访问调用函数中它们的确切名称的数据并不存在。见以下内容:

代码语言:javascript
运行
复制
function PrintVariable(VariableToPrint)
  --we can use debug.getinfo() to determine the name 'VariableToPrint'
  --we cannot determine the name 'MyVariable' without some really convoluted stuff (see comment by VBRonPaulFan on his own answer)
  print(VariableToPrint);
end

MyVariable = 4
PrintVariable(MyVariable)

为了说明这一点,想象一下如果我们做了:

代码语言:javascript
运行
复制
x = 4
MyVariable = x
MyOtherVariable = x
x = nil

PrintVariable(MyVariable)

现在,如果您是Lua,您会在元数据中将什么名称附加到最终被传递给函数的变量上?是的,您可以使用debug.getint()遍历堆栈,查找传入的变量,但您可能会找到几个引用。还应考虑:

代码语言:javascript
运行
复制
PrintVariable("StringLiteral")

你把这个变量叫做什么?它有一个值,但没有名称。

票数 0
EN

Stack Overflow用户

发布于 2012-05-05 04:40:58

你可以用调试库做这样的事情..。像这样的事情做了你想要做的事:

代码语言:javascript
运行
复制
function a_func(arg1, asdf)
    -- if this function doesn't use an argument... it shows up as (*temporary) in 
    -- calls to debug.getlocal() because they aren't used...
    if arg1 == "10" then end
    if asdf == 99 then end
    -- does stuff with arg1 and asdf?
end

-- just a function to dump variables in a user-readable format
function myUnpack(tbl)
    if type(tbl) ~= "table" then
        return ""
    end

    local ret = ""
    for k,v in pairs(tbl) do
        if tostring(v) ~= "" then
            ret = ret.. tostring(k).. "=".. tostring(v).. ", "
        end
    end
    return string.gsub(ret, ", $", "")
end

function hook()
    -- passing 2 to to debug.getinfo means 'give me info on the function that spawned 
    -- this call to this function'. level 1 is the C function that called the hook.
    local info = debug.getinfo(2)
    if info ~= nil and info.what == "Lua" then
        local i, variables = 1, {""}
        -- now run through all the local variables at this level of the lua stack
        while true do
            local name, value = debug.getlocal(2, i)
            if name == nil then
                break
            end
            -- this just skips unused variables
            if name ~= "(*temporary)" then
                variables[tostring(name)] = value
            end
            i = i + 1
        end
            -- this is what dumps info about a function thats been called
        print((info.name or "unknown").. "(".. myUnpack(variables).. ")")
    end
end

-- tell the debug library to call lua function 'hook 'every time a function call
-- is made...
debug.sethook(hook, "c")

-- call a function to try it out...
a_func("some string", 2012)

这导致产出如下:

代码语言:javascript
运行
复制
a_func(asdf=2012, arg1=some string)

你可以做一些漂亮的事情,但这基本上包括了如何做你想要的事情。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10458306

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档