在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
字段的行,问题一定是个问题。
有人可以向我解释我哪里出错了吗?
答案 0 :(得分:1)
尝试使用getfenv(2)
和setfenv(2, t)
代替getfenv(0)
和setfenv(0, t)
。您基本上想要更改封装函数的环境,这将是堆栈级别2。
0是一个特殊参数,它将获取或设置线程的环境,在某些情况下用作默认环境,但这不会影响已经在线程中实例化的各个闭包,因此在这种情况下它不起作用。