Reputation: 123
I would be really interested why this peace of code works at all and prints the same tables.
t = {
f = function()
return t
end
}
print(t)
print(t.f())
My assumption was that t
is only accessible after its definition, thus return t
should fail. However this code seems to contradict.
Upvotes: 3
Views: 133
Reputation: 40613
Since there is no local variable t
in your example, your function accesses the global value t
(that is: _ENV.t
). When your function is called, it accesses the current value of the _ENV variable, then indexes into the "t"
index of that _ENV value. Even though the _ENV table does not contain t
when the function is defined, when it is later called, it does contain t
, and so you are able to access your newly defined table.
local u = {
f = function()
-- Refers to the global variable `t` (that is, _ENV.t).
-- Whenever the function is called, the *current* value of `t` is returned
return t
end
}
print(u) -- prints table: 0xFOOBAR
print(u.f()) -- prints nil
t = u
print(t) --prints table: 0xFOOBAR
print(t.f()) --prints table: 0xFOOBAR
_ENV = {print = print}
print(u.f()) -- prints nil, since _ENV.t is now nil
local _ENV = {print = print, t = u}
print(u.f()) -- still prints nil, because the function definition used the
-- _ENV variable that was lexically visible at the function definition,
-- rather than the new _ENV variable that was just defined.
The use of _ENV means that these examples are only valid for Lua 5.2, but the same principle applies for Lua 5.1.
Upvotes: 4