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

How do I set functions "off limits" in a customized environment?

Asked by
funyun 958 Moderation Voter
8 years ago

Let's say that for whatever reason, I want to prevent myself from using the set/get metatable functions. I have no idea how to do this. Any help?

--Old environment here

excluded = {
    setmetatable,
    getmetatable
}

mt = {
    __metatable = "Locked just in case.",
    __index = getfenv()
}

setfenv(0, setmetatable({}, mt))

--New environment here

a = setmetatable({}, {}) --I don't want this to happen.
b = getmetatable(a) --Or this.

1 answer

Log in to vote
2
Answered by 8 years ago

You'd want to set the function's environment to an empty table, with a metatable using __index to control what you can, and can't do. Which, you got close to, but not quite.

First, let's establish what we don't want anyone to access:

local Blocked = {
    "getmetatable",
    "setmetatable",
}

Now, let's make a function to check if an index is on our list:

function IsBlocked(tab, key)

    -- Iterate the "tab" variable (should be a list)
    for i,v in pairs(tab)do

        -- if v is equal to the key we returned, then ...
        if v==key then

            -- return the key
            return v
        end

    end

    -- No match was found, return nil.
    return nil
end

Set the new environment:

setfenv(1,setmetatable({},{
    __index = function(t, key)

    -- Get the blocked key
        local keyBlocked = IsBlocked(Blocked, key)

    -- if blocked key exists, then ...
        if keyBlocked then
            print("Error: "..keyBlocked.." is locked.")

        -- return nil
            return nil

        else -- If not blocked ...

        -- return old environment index
            return getfenv()[key]
        end
    end
}))

Final product:

local Blocked = {
    "getmetatable",
    "setmetatable",
}

function IsBlocked(tab, key)
    for i,v in pairs(tab)do
        if v==key then
            return v
        end
    end
    return nil
end

setfenv(1,setmetatable({},{
    __index = function(t, key)
        local keyBlocked = IsBlocked(Blocked, key)
        if keyBlocked then
            print("Error: "..keyBlocked.." is locked.")
            return nil
        else
            return getfenv()[key] 
        end
    end,
    __metatable = "no metatable for u",
}))

print(getmetatable) -- > Error: getmetatable is locked.
print(setmetatable) -- > Error: setmetatable is locked.

You can test it here as well: http://repl.it/BCua/1

0
thankya funyun 958 — 8y
0
Np CodingEvolution 490 — 8y
Ad

Answer this question