使用Luabind在Lua中创建的作用域类

时间:2015-09-24 08:47:33

标签: lua luabind

我知道可以使用Luabind向Lua公开的OO系统创建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中的全局命名空间。

2 个答案:

答案 0 :(得分:3)

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')一样使用的函数,自动将类放入{{} 1}}:

MyScope

免责声明:所有这些代码都是未经测试的。

答案 1 :(得分:0)

我的确有点不同,但它的概念基本相同。我没有创造这个类,而只是移动它。我也在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 '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;
    })
];