使用 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;
    })
];