Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

Help with setmetatable and _G?

Asked by 8 years ago

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

Log in to vote
1
Answered by
funyun 958 Moderation Voter
8 years ago

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
Thank you very much sir. CodingEvolution 490 — 8y
Ad

Answer this question