使用Luabind创建Lua范围类

我知道可以使用 Luabind 提供给 Lua 的面向对象系统来创建 Lua 类:

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()

然而,我无法弄清如何在另一个命名空间中设置类,以便可以执行以下操作:

a = MyScope.lua_testclass('example')
a:print()

有人有想法吗?我不希望我的类污染 Lua 的全局命名空间。

点赞
用户2128694
用户2128694

Luabind的class函数将始终污染全局表。但是,您可以在其后进行清理:

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',您必须两次拼写类的名字,但是您可以轻松地在此基础上构建另一个函数,例如setclass(MyScope,'lua_testclass'),自动将类放入MyScope

function setclass(scope,name) scope[name] = newclass(name) end

免责声明:所有这些代码都没有经过测试。

2015-09-24 09:44:40
用户6367853
用户6367853

我做得有些不同,但基本上是相同的概念。我的实现不是创建类,而是移动类。我也在 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) {
        // 在类不存在的情况下,这将只是删除 nil 并返回 nil。这基本上没有任何作用。
        luabind::object oldGlobal = luabind::globals(lua)[name];
        luabind::globals(lua)[name] = luabind::nil;
        return oldGlobal;
    })
];

现在如果你要使用它来移动一个你创建的类,你会这样做:

class 'MyClass'

myTable = {}

myTable.MyClass = moveClass 'MyClass'

另外需要注意的是,如果你希望 moveClass 函数在你尝试移动类不存在的情况下报错,可以使用 luabind::type(oldGlobal) == LUA_TNIL 来判断此类是否存在。

示例:

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;
    })
];
2017-06-24 15:09:19