zoukankan      html  css  js  c++  java
  • lua module package.seeall选项

    module 与 package.seeall

    http://blog.codingnow.com/2006/02/lua_51_module.html

    使用

    module("test")

    后,下面不再看的见前面的全局环境。如果在这个模块里想调用 print 输出调试信息怎么办呢?一个简单的方法是

    local print=print
    module("test")

    这样 print 是一个 local 变量,下面也是可见的。或者可以用

    local _G=_G
    module("test")

    那么 _G.print 也是可以用的。

    当然还有一种巧妙的方式,lua 5.1 提供了一个 package.seeall 可以作为 module 的option 传入

    module("test",package.seeall)

    这样就 OK 了。至于它们是如何工作的,还是自己读源码会理解的清楚一些。

    源码不太好读, 我们下面找文档和做实验来理解。

    为啥使用了 package.seeall, 则此module就可以引用全局环境了呢?

    文档:

    http://www.lua.org/manual/5.1/manual.html

    module (name [, ···])

    This function can receive optional options after the module name, where each option is a function to be applied over the module.

    package.seeall (module)

    Sets a metatable for module with its __index field referring to the global environment, so that this module inherits values from the global environment. To be used as an option to function module.

    使用package.seeall后, 会将当前module的环境表, 设置个 metatable( {__index=_G})

    含义就是, 当你在module声明之后, 如果使用print函数, 则在当前module环境表中存在, 则会想_G表中搜索。

    package.seeall

    static int ll_seeall (lua_State *L) {
      luaL_checktype(L, 1, LUA_TTABLE);
      if (!lua_getmetatable(L, 1)) {
        lua_createtable(L, 0, 1); /* create new metatable */
        lua_pushvalue(L, -1);
        lua_setmetatable(L, 1);
      }
      lua_pushvalue(L, LUA_GLOBALSINDEX);
      lua_setfield(L, -2, "__index");  /* mt.__index = _G */
      return 0;
    }

    测试代码

    module_test.lua

    module(..., package.seeall)

    local print = print
    local getfenv = getfenv
    local tostring = tostring
    local getmetatable = getmetatable

    --module("module_test")


    local function printTable(tbl)

        for k,v in pairs(tbl) do
            print("kay="..tostring(k) .. "  value="..tostring(v))
        end

    end


    varone = 1

    local strkey = "vartwo"


    -- 本模块环境
    local env = getfenv(1)

    env[strkey] = 2

    print("vartwo="..vartwo)

    print("getfenv(1) ="..tostring( ( getfenv(1) ) ) )

    print("getfenv(1) metatable="..tostring( getmetatable( getfenv(1) ) ) )

    print("--------------- before getmetatable( getfenv(1) ) -------------")
    printTable( getmetatable( getfenv(1) ) )
    print("--------------- after getmetatable( getfenv(1) ) -------------")

    -- 调用此模块的环境
    local env_caller = getfenv(2)

    env["env_caller"] = env_caller

    print("getfenv(2) ="..tostring(getfenv(2)))

    main.lua


    local testmodule = require("module_test")

    var_caller = 55

    print("testmodule.vartwo=" .. testmodule.vartwo)


    local function printTable(tbl)

        for k,v in pairs(tbl) do
            print("kay="..tostring(k) .. "  value="..tostring(v))
        end

    end


    print("----------- testmodule ------------------")

    printTable(testmodule)

    print("-----------  testmodule.env_caller ------------------")

    printTable(testmodule.env_caller)

    打印结果

    >lua -e "io.stdout:setvbuf 'no'" "main.lua"
    vartwo=2
    getfenv(1) =table: 006F9438
    getfenv(1) metatable=table: 006F92D0
    --------------- before getmetatable( getfenv(1) ) -------------
    kay=__index  value=table: 006F2650
    --------------- after getmetatable( getfenv(1) ) -------------
    getfenv(2) =table: 006F2650

    testmodule.vartwo=2
    ----------- testmodule ------------------
    kay=_NAME  value=module_test
    kay=_PACKAGE  value=
    kay=varone  value=1
    kay=_M  value=table: 006F9438
    kay=vartwo  value=2
    kay=env_caller  value=table: 006F2650
    -----------  testmodule.env_caller ------------------
    kay=string  value=table: 006F9730
    kay=xpcall  value=function: 006F6788
    kay=module_test  value=table: 006F9438
    kay=package  value=table: 006F7110
    kay=tostring  value=function: 006F6968
    kay=print  value=function: 006F6CC8
    kay=os  value=table: 006F9848
    kay=unpack  value=function: 006F6A08
    kay=require  value=function: 006F7C98
    kay=getfenv  value=function: 006F6E08
    kay=setmetatable  value=function: 006F66A8
    kay=next  value=function: 006F6C88
    kay=assert  value=function: 006F6D48
    kay=tonumber  value=function: 006F6888
    kay=io  value=table: 006F96E0
    kay=rawequal  value=function: 006F6DC8
    kay=collectgarbage  value=function: 006F6D28
    kay=arg  value=table: 006F92A8
    kay=getmetatable  value=function: 006F6AE8
    kay=module  value=function: 006F7B98
    kay=rawset  value=function: 006F6AA8
    kay=var_caller  value=55
    kay=math  value=table: 006F96B8
    kay=debug  value=table: 006F91E0
    kay=pcall  value=function: 006F6CE8
    kay=table  value=table: 006F7160
    kay=newproxy  value=function: 006F0568
    kay=type  value=function: 006F6A48
    kay=coroutine  value=table: 006F7340
    kay=_G  value=table: 006F2650
    kay=select  value=function: 006F6B48
    kay=gcinfo  value=function: 006F6D88
    kay=pairs  value=function: 006F0538
    kay=rawget  value=function: 006F6A88
    kay=loadstring  value=function: 006F6B08
    kay=ipairs  value=function: 006F2BD0
    kay=_VERSION  value=Lua 5.1
    kay=dofile  value=function: 006F6DE8
    kay=setfenv  value=function: 006F6A28
    kay=load  value=function: 006F6B88
    kay=error  value=function: 006F6D68
    kay=loadfile  value=function: 006F6DA8
    >Exit code: 0

  • 相关阅读:
    C字符串处理函数
    C语言字符串函数大全
    那些闪亮的日子
    牛客网在线编程:幸运数
    牛客网在线编程:水仙花数
    [LeetCode]617.Merge Two Binary Trees
    [LeetCode]657.Judge Route Circle
    [LeetCode]141. Linked List Cycle
    五大算法:分治,贪心,动态规划,回溯,分支界定
    [LeetCode]387.First Unique Character in a String
  • 原文地址:https://www.cnblogs.com/lightsong/p/5743188.html
Copyright © 2011-2022 走看看