【问题标题】:Scoping classes created in Lua using Luabind使用 Luabind 在 Lua 中创建的范围类
【发布时间】:2017-06-24 23:09:19
【问题描述】:

我知道 Lua 类可以使用 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()

但是我无法弄清楚如何在另一个命名空间中确定类的范围,因此我可以执行以下操作:

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

任何人都有想法。我不希望我的类污染 Lua 中的全局命名空间。

【问题讨论】:

    标签: lua luabind


    【解决方案1】:

    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
    

    免责声明:所有这些代码完全未经测试。

    【讨论】:

      【解决方案2】:

      我的做法略有不同,但大体上是相同的概念。我的不创建类,而只是移动它。我也在 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;
          })
      ];
      

      【讨论】:

        猜你喜欢
        • 2014-08-05
        • 1970-01-01
        • 2011-11-18
        • 2011-03-04
        • 2010-12-28
        • 1970-01-01
        • 2012-07-20
        • 2011-09-06
        • 1970-01-01
        相关资源
        最近更新 更多