I've been playing around with environment manipulation, and ran into something that really stumbled me. When you try to index a nil value in an environment or table, it should invoke the __index metamethod (if one is set to it). However in my case, it's not doing that. Here's my code:
function Test(x) print(x) -- print's nil end setfenv(Test,setmetatable({},{ __index=function(t,k) if(k=='x')then print("No '"..k.."' value exists, returning default...") return "Replaced with this string" else return getfenv()[k] end end })) Test() -- not assigning any parameters (so, "x" should be nil, therefore allowing "__index" to be invoked when the environment is indexed for "x", like in it's print function above).
Yet, the output still prints "nil". Can anyone help please? Is there any way I can use __index on this function without getting rid of it's argument?
As far as I can tell, lua does not consider x to be undefined because it is receiving the variable as a parameter (even though x is still nil, it is being set to nil when Test runs). If you remove the x parameter from the function, the index metamethod is called:
function Test() print(x) -- prints "Replaced with this string" end setfenv(Test,setmetatable({},{ __index=function(t,k) if(k=='x')then print("No '"..k.."' value exists, returning default...") return "Replaced with this string" else return getfenv()[k] end end })) Test()
If you want to look into this behaviour further, I would recommend looking into lua disassembling tools.