在Roblox中设置当前环境的__index

时间:2015-07-01 23:33:42

标签: lua roblox

在Roblox Studio中,我有一个ModuleScript对象,它实现了类似于第一版编程在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

然后我尝试使用以下脚本来访问Account类,假设第二个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),因此对于我设置__index h4x0r.Account字段的行,问题一定是个问题。

有人可以向我解释我哪里出错了吗?

1 个答案:

答案 0 :(得分:1)

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

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