代码之家  ›  专栏  ›  技术社区  ›  Zack Lee

如何创建可重新创建的自定义需求

  •  1
  • Zack Lee  · 技术社区  · 6 年前

    我创造了我的习惯 require Lua中的函数,但当我多次创建函数时,它似乎无法替换先前创建的 要求 功能。

    我想替换(或覆盖)上一个 要求 功能时间到时间。

    我的代码:

    #include "lua.hpp"
    
    int main()
    {
        lua_State *L = luaL_newstate();
        luaL_openlibs(L);
        luaopen_my(L);
        lua_settop(L, 0);
        for (int i = 0; i < 2; ++i)
        {
            luaL_dostring(L, "local require_original = require\n"
                             "function require(name, ...)\n"
                                 "print('Hello World')\n"
                                 "local val = table.pack(require_original(name, ...))\n"
                                 "return table.unpack(val,1,val.n)\n"
                             "end\n");
            luaL_dostring(L, "package.preload['A'] = function()\n"
                                 "local a = {}\n"
                                 "print('A required')\n"
                                 "return a\n"
                             "end\n");
            luaL_dostring(L, "local a = require 'A'");
            luaL_dostring(L, "package.preload['A'] = nil package.loaded['A'] = nil");
        }
        lua_close(L);
    }
    

    我得到的结果是:

    Hello World
    A required
    Hello World
    Hello World
    A required
    

    我期望的结果是:

    Hello World
    A required
    Hello World
    A required
    

    为了得到我期望的结果,我应该改变什么?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Egor Skriptunoff    6 年前

    您可以在全局命名空间中提供特殊的“uninstall”函数:-)
    首先在内部替换lua代码 luaL_dostring 包括以下内容:

    if uninstall_my_require then
       uninstall_my_require()
    end
    local require_original = require
    local function my_require(name, ...)
       print('Hello World')
       local val = table.pack(require_original(name, ...))
       return table.unpack(val,1,val.n)
    end
    require = my_require 
    function uninstall_my_require()
       if require == my_require then
          require = require_original
       end
       uninstall_my_require = nil
    end
    
        2
  •  2
  •   Jason Goemaat    6 年前

    第一次通过你设置全球 require 函数转换为新函数,第二次保存时 你的新功能 并将其设置为另一个实例。Lua的情况是这样的:

    local require_original1 = require
    function require(name, ...)
       print('Hello World')
       local val = table.pack(require_original1(name, ...))
       return table.unpack(val,1,val.n)
    end
    
    local require_original2 = require -- now the function above
    function require(name, ...) -- redefine yet again
       print('Hello World')
       -- require_original2 is your function above
       local val = table.pack(require_original2(name, ...))
       return table.unpack(val,1,val.n)
    end
    

    您只需跟踪原始的require函数一次,或者使用egor's answer之类的卸载函数,或者将其更改为只分配一次的全局函数:

    require_original = require_original or require