使用 Luabind 在 Lua 中创建范围 类
Scoping classes created in Lua using Luabind
我知道 Lua classes 可以使用 Luabind 公开给 Lua 的 OO 系统创建:
http://www.rasterbar.com/products/luabind/docs.html#defining-classes-in-lua
class 'lua_testclass'
function lua_testclass:__init(name)
self.name = name
end
function lua_testclass:print()
print(self.name)
end
a = lua_testclass('example')
a:print()
但是我无法弄清楚如何在另一个命名空间内确定 class 的范围,因此我可以执行以下操作:
a = MyScope.lua_testclass('example')
a:print()
任何人都有想法。我不希望我的 classes 污染 Lua.
中的全局命名空间
Luabind 的class
函数总是会污染全局table。但是,您可以在它之后进行清理:
function newclass(name)
oldglobal = _G[name]
class(name)
cls = _G[name]
_G[name] = oldglobal
return cls
end
然后你会像这样使用它:
MyScope.lua_testclass = newclass 'lua_testclass'
类似于 local mod = require 'mod'
你必须拼写 class 的名字两次,但你可以很容易地在此基础上构建另一个可以像 setclass(MyScope, 'lua_testclass')
一样自动使用的函数将 class 放入 MyScope
:
function setclass(scope, name) scope[name] = newclass(name) end
免责声明:所有这些代码都完全未经测试。
我的做法略有不同,但大体上是相同的概念。我的不创建 class,而只是移动它。我也在 C++ 端实现了它。
要实现我在 Lua 中所做的事情,您可以这样写:
function moveClass(name)
oldGlobal = _G[name]
_G[name] = nil
return oldGlobal
end
要用 C++ 实现它,您可以这样写:
luabind::module(lua) [
luabind::def("moveClass", +[](lua_State * lua, std::string name) {
// In the case the class does not exist, this will just
// remove nil and return nil. That essentially does nothing.
luabind::object oldGlobal = luabind::globals(lua)[name];
luabind::globals(lua)[name] = luabind::nil;
return oldGlobal;
})
];
所以现在如果你要用它来移动你创建的 class,你会这样做:
class 'MyClass'
myTable = {}
myTable.MyClass = moveClass 'MyClass'
作为额外说明,如果您希望 moveClass 函数在您尝试移动的 class 不存在的情况下给出错误,请使用 luabind::type(oldGlobal) == LUA_TNIL判断class是否存在
示例:
luabind::module(lua) [
luabind::def("moveClass", +[](lua_State * lua, std::string name) {
luabind::object oldGlobal = luabind::globals(lua)[name];
if (luabind::type(oldGlobal) == LUA_TNIL) {
throw std::runtime_error("Class does not exist.");
}
luabind::globals(lua)[name] = luabind::nil;
return oldGlobal;
})
];
我知道 Lua classes 可以使用 Luabind 公开给 Lua 的 OO 系统创建:
http://www.rasterbar.com/products/luabind/docs.html#defining-classes-in-lua
class 'lua_testclass'
function lua_testclass:__init(name)
self.name = name
end
function lua_testclass:print()
print(self.name)
end
a = lua_testclass('example')
a:print()
但是我无法弄清楚如何在另一个命名空间内确定 class 的范围,因此我可以执行以下操作:
a = MyScope.lua_testclass('example')
a:print()
任何人都有想法。我不希望我的 classes 污染 Lua.
中的全局命名空间Luabind 的class
函数总是会污染全局table。但是,您可以在它之后进行清理:
function newclass(name)
oldglobal = _G[name]
class(name)
cls = _G[name]
_G[name] = oldglobal
return cls
end
然后你会像这样使用它:
MyScope.lua_testclass = newclass 'lua_testclass'
类似于 local mod = require 'mod'
你必须拼写 class 的名字两次,但你可以很容易地在此基础上构建另一个可以像 setclass(MyScope, 'lua_testclass')
一样自动使用的函数将 class 放入 MyScope
:
function setclass(scope, name) scope[name] = newclass(name) end
免责声明:所有这些代码都完全未经测试。
我的做法略有不同,但大体上是相同的概念。我的不创建 class,而只是移动它。我也在 C++ 端实现了它。
要实现我在 Lua 中所做的事情,您可以这样写:
function moveClass(name)
oldGlobal = _G[name]
_G[name] = nil
return oldGlobal
end
要用 C++ 实现它,您可以这样写:
luabind::module(lua) [
luabind::def("moveClass", +[](lua_State * lua, std::string name) {
// In the case the class does not exist, this will just
// remove nil and return nil. That essentially does nothing.
luabind::object oldGlobal = luabind::globals(lua)[name];
luabind::globals(lua)[name] = luabind::nil;
return oldGlobal;
})
];
所以现在如果你要用它来移动你创建的 class,你会这样做:
class 'MyClass'
myTable = {}
myTable.MyClass = moveClass 'MyClass'
作为额外说明,如果您希望 moveClass 函数在您尝试移动的 class 不存在的情况下给出错误,请使用 luabind::type(oldGlobal) == LUA_TNIL判断class是否存在
示例:
luabind::module(lua) [
luabind::def("moveClass", +[](lua_State * lua, std::string name) {
luabind::object oldGlobal = luabind::globals(lua)[name];
if (luabind::type(oldGlobal) == LUA_TNIL) {
throw std::runtime_error("Class does not exist.");
}
luabind::globals(lua)[name] = luabind::nil;
return oldGlobal;
})
];