Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Help with setmetatable and _G?

Trying to lock a variable (and it's value) in _G, by making a new environment and resetting a changed _G variable back to default, if attempted to change it.

-- CodingEvolution
-- Locking variables (and values) in _G

_G={} -- New _G
_G.x=1 
_G.y=2

setfenv(1,setmetatable({},{
    __index=function(t,k)
        if k=='_G' then
            return setmetatable({},{
                __newindex=function(t,k,v)
                    if k=='x' then
                        print'This value is locked; changing back to default.'
                        rawset(t,k,_G[k]) -- should set back to 1, but doesn't?
                    else
                        print'changing global...'
                        rawset(t,k,v) -- again, should return normal. but returns nothing (nil).
                    end
                end
            })
        end
    return getfenv()[k] -- If not _G, return old environment and index.
    end
}))

print(_G.y) --> "nil" shouldn't it be 2?

_G.x='Changed' --> as expected, it triggers the __newindex function.

print(_G.x) --> but even then, it still returns nil.

-- I have to be somewhat close, because it does detect when and if a value in _G changed. It just
-- Doesn't do anything about it. 

Shouldn't rawset return the value of _G[k] from the previous environment? If not, why? Thank you for reading.

-- EDIT: You can run this code and test it here: http://repl.it/BCF6

1 answer

✓ Accepted answer

I suppose you just have to set __index to _G, since the table is empty.

_G={}
_G.x=1
_G.y=2

setfenv(1,setmetatable({},{
    __index=function(t,k)
        if k=='_G' then
            return setmetatable({},{
                __newindex=function(t,k,v)
                    if k=='x' then
                        print'This value is locked; changing back to default.'
                        rawset(t,k,_G[k])
                    else
                        print'changing global...'
                        rawset(t,k,v)
                    end
                end,

				__index=_G, --See? Index is _G.
				__metatable = "This metatable is locked." --Lock up that metatable!
            })
        end
    return getfenv()[k]
    end
}))

print(_G.y)

_G.x='Changed'

print(_G.x)

1 comment

1

Thank you very much sir.

This discussion is preserved as it was. New answers, comments, and votes are closed.