|
| 26 Jan 2015 01:07 PM |
Note, this is in Lua 5.3
So, I'm trying to set variables as read-only, but this doesn't work.
io.write(_VERSION..'\n'); _e = _ENV; read_only = {};
function setReadOnly(v) if(getmetatable(_e)==nil) then setmetatable(_e,{ __index = function(self,k) if(read_only[k]) then return read_only[k] end; end; }); end; rawset(read_only,v,_e[v]); end;
local a = 'hi'; setReadOnly('a'); print(a); a='no'; print(a);
However, this does.
io.write(_VERSION..'\n'); _e = _ENV; read_only = {};
function setReadOnly(v) if(getmetatable(_e)==nil) then setmetatable(_e,{ __index = function(self,k) if(read_only[k]) then return read_only[k] end; end; }); end; rawset(read_only,v,_e[v]); end;
local a = 'hi'; setReadOnly('a'); print(a); _e.a='no'; print(a);
All that's different is I get the variable from the environment table. Do you not reference the environment when accessing a variable normally? |
|
|
| Report Abuse |
|
|
| |
|
|
| 26 Jan 2015 01:14 PM |
| Well, it works that way in Roblox. |
|
|
| Report Abuse |
|
|
robocu3
|
  |
| Joined: 13 Mar 2009 |
| Total Posts: 6485 |
|
|
| 26 Jan 2015 01:16 PM |
I hardly use Lua outside of ROBLOX, I don't really deem it useful for much. I haven't used the newest version. free bump though. -=Robo=- |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 01:31 PM |
And now I've got a C stack-overflow.
local read_only = {}; do
setmetatable(read_only,{ __index = function(t,k) return t[k] end; });
setmetatable(_ENV,{ __index = function(t,k) if(read_only[k]~=nil) then return read_only[k] else return t[k] end end; });
end;
function makeReadOnly(var) rawset(read_only, var, _ENV[var]); end;
local a = 'hello'; makeReadOnly('a'); io.write(a..'\n'); a = 'fool'; io.write(a..'\n'); |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 01:51 PM |
Apparently, my function is nil now?
local read_only = {}; do
setmetatable(read_only,{ __index = function(t,k) return rawget(t,k) end; });
setmetatable(_ENV,{ __index = function(t,k) if(read_only[k]~=nil) then return read_only[k] else return rawget(t,k) end end, __newindex = function(t,k,v) if(read_only[k]~=nil) then return 'lol' end end; });
end;
function makeReadOnly(var) rawset(read_only, var, _ENV[var]); end;
local a = 'hello'; makeReadOnly('a'); io.write(a..'\n'); a = 'fool'; io.write(a..'\n'); |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 01:58 PM |
Is this what you want
setmetatable(_ENV, { __index = function(x) print("omg") end })
a = b -->omg |
|
|
| Report Abuse |
|
|
digpoe
|
  |
| Joined: 02 Nov 2008 |
| Total Posts: 9092 |
|
|
| 26 Jan 2015 03:04 PM |
local function MakeReadOnly(tab) -- Assumes that table 'tab' does not already have a metatable set local proxy = { } return setmetatable(proxy, { __index = tab, -- redirects index to original table __newindex = function(_, key) -- error whenever a key is written to return error(string.format("Attempt to write key '%s' on a write-protected table", key), 2) end, __metatable = "Locked" -- prevents people from removing write-protection }) end
Should work. Makes the table specified in 'tab' read-only. |
|
|
| Report Abuse |
|
|
digpoe
|
  |
| Joined: 02 Nov 2008 |
| Total Posts: 9092 |
|
|
| 26 Jan 2015 03:05 PM |
| I should mention that since in Lua versions greater than 5.1 that _ENV is a table, trying to read from it in a __index should be done using rawget() as that bypasses metamethods. |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 04:25 PM |
Mhm, but I'm attempting to make ANY variable read-only, not just tables.
::_::goto_ |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 04:27 PM |
| He just said the environment is a table. That means that all of your variables are keys to that table. He didn't say anything about your variables being tables. |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 04:49 PM |
No, Jarod, he meant that you call the function on the table you want to lock. If I were to use that function on _ENV, I wouldn't be able to read or write to any variable, not just the ones I want to make read-only.
::_::goto_ |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Jan 2015 05:37 PM |
I didn't completely read everything but I noticed a local variable.
Local variables are not stored in the function/global environment so: local x = 5; print(_ENV.x); Would be nil |
|
|
| Report Abuse |
|
|
|
| 26 Jan 2015 05:41 PM |
k, this doesn't work either
local read_only = {}; do
setmetatable(read_only,{ __index = function(t,k) return rawget(t,k) end; });
setmetatable(_ENV,{ __index = function(t,k) if(read_only[k]~=nil) then return read_only[k] else return rawget(t,k) end end, __newindex = function(t,k,v) if(read_only[k]~=nil) then return 'lol' else rawset(t,k,v); end end; });
end;
function makeReadOnly(var) rawset(read_only, var, _ENV[var]); end;
a = 'hello'; makeReadOnly('a'); io.write(a..'\n'); a = 'fool'; io.write(a..'\n'); |
|
|
| Report Abuse |
|
|
cntkillme
|
  |
| Joined: 07 Apr 2008 |
| Total Posts: 44956 |
|
|
| 26 Jan 2015 05:43 PM |
| __newindex is only invoked when it was already nil, so with your setup the best you can get is "non-creatable global variables" as opposed to "readonly global variables" |
|
|
| Report Abuse |
|
|