2

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

然后我尝试使用以下脚本访问 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

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

4

1 回答 1

1

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

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

于 2015-07-02T02:22:18.610 回答