1

I have a script which I load with loadfile and then run it. Also I have the variable love in the scope of parent lua script and I want this variable be nil inside the child script enivornment but everything else untouched (print, math, pairs, all the std lib of Lua). How can I do that?

This does not work:

local scenario = love.filesystem.load(script)
local env = {}
setmetatable(env, { __index = _G })
env.love = nil
env.game = Game
setfenv(scenario, env)
Egor Skriptunoff
  • 23,359
  • 2
  • 34
  • 64
VP.
  • 15,509
  • 17
  • 91
  • 161

2 Answers2

2
local scenario = love.filesystem.load(script)
local env = setmetatable({}, { __index = 
   function(t, k)
      if k == "love" then
         return nil
      else
         return _G[k]
      end
   end
})
setfenv(scenario, env)
Egor Skriptunoff
  • 906
  • 1
  • 8
  • 23
  • Note that `setfenv` [was removed in Lua 5.2](https://www.lua.org/manual/5.2/manual.html#8.2). – ComicSansMS Oct 06 '17 at 13:15
  • @ComicSansMS - This question is about Lua 5.1, as the author uses this function in his code (look also previous question of this author). – Egor Skriptunoff Oct 06 '17 at 15:05
  • @EgorSkriptunoff Agreed, I just added the comment in case someone stumbles across this question in the future and wonders why your answer doesn't work for them. – ComicSansMS Oct 06 '17 at 18:15
  • @ComicSansMS - I've added "Lua 5.1" tag to the question to avoid possible misunderstanding (actually, this question is about Love2D working over Lua5.1) – Egor Skriptunoff Oct 06 '17 at 19:18
1

Your code does not work because env inherits from _G and so env.love is resolved in _G. Setting env.love = nil does not add a love entry to env.

Set env.love = false or env.love = {}.

lhf
  • 70,581
  • 9
  • 108
  • 149
  • Why setting it to `nil` does not add it? – VP. Oct 06 '17 at 14:03
  • Setting to `nil` removes an entry in a table. – lhf Oct 06 '17 at 14:04
  • but it does not - the child script still can use `love` in it's scope. – VP. Oct 06 '17 at 14:05
  • 1
    `env.love` is already `nil` *before* the line `env.love = nil` executes, so that line doesn't do anything. When you access `env.love`, the `__index` metamethod is invoked precisely *because* the true value of `env.love` is `nil`; this is exactly the behavior which the manual specifies. – Tanner Swett Oct 06 '17 at 14:52