Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The canonical reference for this is <a href="http://www.lua.org/pil/14.3.html" rel="nofollow noreferrer">link text</a>. Explaining this briefly we'll work off the following code from the site:</p> <pre><code>a = 1 local newgt = {} -- create new environment setmetatable(newgt, {__index = _G}) setfenv(1, newgt) -- set it </code></pre> <p>The first line sets up the (global) variable "a". You can view this as setting default values for your code. (Keep in mind that in Lua all variables are global unless you declare them with "local".)</p> <p>The next line creates a table that will be your new environment. It is local to the function/chunk you're executing in so it won't be trashed by anything else that runs now or later.</p> <p>The third line is the beginnings of the magic. To understand it you're going to have to understand <a href="http://lua-users.org/wiki/MetamethodsTutorial" rel="nofollow noreferrer">metamethods</a> In essence, however, you're using Lua's metamagic to ensure that any global names that aren't defined in your soon-to-be function environment get resolved in the context of your old global environment. Basically it means if you use a name that's not in your function environment, Lua will automagically hunt in the global environment you used to have to find the name. (In a word: inheritance.)</p> <p>The fourth line is where you get what you're looking for. Setfenv(1,...) means that this changes the environment for your current function. (You could use 2 for the calling function, 3 for the calling function's caller, etc. on up the line.) The second parameter is the table you just set up, complete with inheritance of the old behaviour. Your function is now executing in a new global environment. It has all the names and values of the old environment handy (including functions and that global variable "a" you put in). If, however, you WRITE to a name it will not overwrite the global state. It will overwrite your local copy of it.</p> <p>Consider the following subsequent code:</p> <pre><code>a = 10 b = 20 </code></pre> <p>What you have done now is made your function environment table look like this:</p> <pre><code>{a = 10, b=20} </code></pre> <p>Your "global" environment, in short, contains two variables only: a (value 10) and b (value 20). When you access "a" later you'll get your local copy with 10 -- the old global value stored in your metatable is shadowed now and is still set to 1 -- and if you access "b" you'll get 20, despite the original global state likely not even having a variable "b" to access. And you'll still be able to access all the functions, etc. you've defined before this point as well.</p> <hr> <p><em>Edited to add test code to debug OP's problem.</em></p> <p>I put the following code into "junk.lua":</p> <pre><code>a = 1 local newgt = {} setmetatable(newgt, {__index = _G}) setfenv(1, newgt) print(a) a = 10 print(a) print(newgt) </code></pre> <p>The output of it is as follows:</p> <pre><code>$ lua junk.lua 1 10 table: 0x976d040 </code></pre> <p>This is using Lua 5.1.4. What is the output you're seeing?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload