在 Roblox 中设置当前环境 __index

Setting __index of current environment in Roblox

在 Roblox Studio 中,我有一个 ModuleScript 对象,它实现了一个类似于 class Programming In Lua 第一版第 16 章中所示的对象,如下所示:

local h4x0r = { }

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

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

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

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

上面的脚本因错误 Workspace.Script:5: attempt to call method 'withdraw' (a nil value) 而失败,因此这一定是我设置 h4x0r.Account__index 字段的行的问题。

谁能解释一下我哪里错了?

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

0 是一个特殊参数,它将获取或设置 线程 的环境,它用作 默认环境在某些情况下,但这不会影响已经在线程中实例化的各个闭包,因此在这种情况下不起作用。