将当前环境中的__index设置为Roblox。

在Roblox Studio中,我有一个ModuleScript对象,它实现了与《Lua编程》第一版第16章中所示类似的类,如下所示:


local function setCurrentEnvironment(t, env)
    if (not getmetatable(t)) then
        setmetatable(t, { __index = getfenv(0) })
    end

    setfenv(0, t)
end

do
    setCurrentEnvironment(h4x0r);

    do
        h4x0r.Account = {};
        setCurrentEnvironment(h4x0r.Account);
        __index = h4x0r.Account;

        function withdraw(self, v)
            self.balance = self.balance - v;
            return self.balance;
        end

        function deposit(self, v)
            self.balance = self.balance + v;
            return self.balance;
        end

        function new()
            return setmetatable({ balance = 0 }, h4x0r.Account)
        end

        setCurrentEnvironment(h4x0r);
    end
end

return h4x0r

然后我尝试使用以下脚本来访问Account类,假设第二个do-end块的所有成员都将分配给h4x0r.Account:

h4x0r = require(game.Workspace.h4x0r);
Account = h4x0r.Account;

account = Account.new();
print(account:withdraw(100));

上面的脚本失败并显示错误Workspace.Script:5:尝试调用方法'withdraw'(空值),因此它必须是关于我设置h4x0r.Account__index字段的问题。

有人可以解释一下我错在哪里吗?

点赞
用户903234
用户903234

尝试使用 getfenv(2)setfenv(2, t),而不是 getfenv(0)setfenv(0, t)。您实际上想要更改_封装函数_的环境,这将是堆栈级别2。

0是一个特殊的参数,它可以获取或设置线程的环境,该线程在某些情况下用作_默认环境_,但不影响已在线程中实例化的单个闭包,因此在此情况下无效。

2015-07-02 02:22:18