在Lua 5.1中为相同的功能设置不同的环境

时间:2014-08-21 10:53:01

标签: lua luajit lua-5.1

我想在Lua 5.1 (luajit)中为同一个函数设置不同的环境:

f = function() print(a) end
b = setfenv(f, { a = 1, print = print })
c = setfenv(f, { a = 2, print = print })

我希望b()c()打印不同的数字

我已经通过创建基于string.dump的新功能块并将env绑定到它来破解了一种方式,但是有更好的方式吗?或者,某个函数可以根据某些条件以某种方式具有不同的upvalues吗?

function bind_env(f, env)
  return setfenv(loadstring(string.dump(f)), env)
end

谢谢!

1 个答案:

答案 0 :(得分:1)

函数的upvalues由其词法范围决定:

function test(a, b)
   function func(x) -- sees x, a and b
       print(a*x+b)
   end
   return func
end

f12 = test(1, 2) -- x+2
f23 = test(2, 3) -- 2x+3

f12(4)
f23(4)

最后两行打印6和11.从技术上讲,test(a,b)为每个a,b返回一个不同的函数对象,但从概念上讲,它返回相同函数的不同闭包(字节码的序列相同)。所以,如果你有

function func(a)
    return function() print(a) end
end 

你可以为每个a定义一个不同的闭包:

b = func(1) -- a=1
c = func(2) -- a=2

但请注意b==c是假的,但这可能是一件好事。