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