zoukankan      html  css  js  c++  java
  • lua 模块功能

    lua5.1 模块理解

    http://www.lua.org/manual/5.1/manual.html#pdf-module

    模块

    5.3 – Modules

    The package library provides basic facilities for loading and building modules in Lua. It exports two of its functions directly in the global environment: require and module. Everything else is exported in a table package.

    package库提供了基本的功能,可以实现加载和构建模块。

    此库开放了两个接口在全局环境中(_G) require module ,

    除了这两个接口,其他所有功能都开放到package表中。

    实际上 require 文件 的结果 都存储在 package.loaded 表中。   例如 require “xxx”,   结果是 package.loaded[“xxx”]  = yyy (yyy 是 xxx.lua 执行结果的返回值)。

    require

    require (modname)

    Loads the given module. The function starts by looking into the package.loaded table to determine whether modname is already loaded. If it is, then require returns the value stored at package.loaded[modname]. Otherwise, it tries to find a loader for the module.

    require 语句, 会先查询 package.loaded 表, 如果表中存在, 则将 package.loaded[modname]的值作为 require 的返回值。 否则, 尝试查询模块的 loader。

    To find a loader, require is guided by the package.loaders array. By changing this array, we can change how require looks for a module. The following explanation is based on the default configuration for package.loaders.

    查询 loaders, 需要按照 package.loaders数组顺序查询loader。

    First require queries package.preload[modname]. If it has a value, this value (which should be a function) is the loader. Otherwise require searches for a Lua loader using the path stored in package.path. If that also fails, it searches for a C loader using the path stored in package.cpath. If that also fails, it tries an all-in-one loader (see package.loaders).

    首先 require 查询 package.preload表,如果失败,

    然后使用 package.path存储的路径查找 lua loader, 如果失败,

    然后使用package.cpath春初的路径查找 c loader, 如果失败,

    则尝试 all-in-one loader。

    Once a loader is found, require calls the loader with a single argument, modname. If the loader returns any value, require assigns the returned value to package.loaded[modname]. If the loader returns no value and has not assigned any value to package.loaded[modname], then require assigns true to this entry. In any case, require returns the final value of package.loaded[modname].

    如果loader找到, 则 调用 此loader, 入参为一个字符串 modname。  

    loader(modname)

    如果loader调用有返回任何值, 则设置这个返回值到 package.loaded[modname]中。

    如果 loader调用没有返回值, 或者没有设置package.loaded[modname], 则 require 设置true给package.loaded[modname]。

    理解: 对于lua文件, 对应的一个loader, 此loader是一个函数, 函数的环境为 require执行的环境,

    lua:

    local a = 111

    print(a)

    return a

    loader:

    function xx_loader( modname )

            local a = 111

           print(a)

           return a

    end

    If there is any error loading or running the module, or if it cannot find any loader for the module, then require signals an error.

    module

    module (name [, ···])

    Creates a module. If there is a table in package.loaded[name], this table is the module. Otherwise, if there is a global table t with the given name, this table is the module. Otherwise creates a new table t and sets it as the value of the global name and the value of package.loaded[name]. This function also initializes t._NAME with the given name, t._M with the module (t itself), and t._PACKAGE with the package name (the full module name minus last component; see below). Finally, module sets t as the new environment of the current function and the new value of package.loaded[name], so that require returns t.

    http://www.cnblogs.com/orez88/articles/2139160.html

    • module

    当在模块文件中使用module函数的时候,如下所示;

    1. module “mymodule” 

    实际上等同于以下的语句:

    1. local modname = “mymodule”     – 定义模块名  
    2. local M = {}                               -- 定义用于返回的模块表  
    3. _G[modname] = M                      -- 将模块表加入到全局变量中  
    4. package.loaded[modname] = M    -- 将模块表加入到package.loaded中,防止多次加载  
    5. setfenv(1,M)                               -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中 

    通过module(),可以方便的编写模块中的内容。

    If name is a compound name (that is, one with components separated by dots), module creates (or reuses, if they already exist) tables for each component. For instance, if name is a.b.c, then module stores the module table in field c of field b of global a.

    将 路径层级 和 命名空间层级 完美契合:

    module 文件  存储在 test/newModule.lua文件中

    module(..., package.seeall)

    dingzhiprint = function ()

        print("nasView print ----22 55")

    end

    调用文件, 为  test.lua, 其使用方法  与路径一致。

    require("test.newModule")

    test.newModule.dingzhiprint()

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

    lua5.2 module 不建议使用原因

    1、 module 的接口 增加了开发者理解难度:

    需要在 module 声明前, 将需要使用的 变量 local 声明, 不能直接使用全局变量。 虽然可以应用 package.seeall 可以解决这个问题, 还是不够直接。

    1. local modname = “mymodule”     – 定义模块名  
    2. local M = {}                               -- 定义用于返回的模块表  
    3. _G[modname] = M                      -- 将模块表加入到全局变量中  
    4. package.loaded[modname] = M    -- 将模块表加入到package.loaded中,防止多次加载  
    5. setfenv(1,M)                               -- 将模块表设置为函数的环境表,这使得模块中的所有操作是以在模块表中的,这样定义函数就直接定义在模块表中 

    2、 module语法破坏了全局环境, 可能导致命名冲突。

    module(…)用法不会导致冲突,  但是如果用户自定义 modname, 则若干模块很容易冲突,

    例如 a b 两个文件夹, a/a.lua 定义了 module(“test”)   b/b.lua 也定义了 module(“test”),

    则造成冲突。

    http://dhq.me/lua-learning-notes-package-and-module

    https://john.nachtimwald.com/2014/07/19/writing-lua-modules/

    lua 5.2 推荐使用方法:

    local M = {}

    function M.func1()

    print("func1")

    end

    function M.func2()

    print("func2")

    end

    return M

    local fm = require("functions_module")

    fm.func1()

    fm.func2()

  • 相关阅读:
    第一章:计算机网络参考模型
    阿里云ECS hadoop+spark+zookeeper+hive code-server 集群搭建
    IDEA SSM+MAVEN+JWT 图书管理系统
    IDEA SSM后端框架入门
    code-server Command ' ' not found
    code-server scala error: object apache is not a member of package org
    下面给出一个child-parent的表格,要求挖掘其中的父子辈关系,给出祖孙辈关系的表格。
    现在有多个输入文件,每个文件中的每行内容均为一个整数。要求读取所有文件中的整数,进行升序排序后,输出到一个新的文件中,输出的数据格式为每行两个整数,第一个整数为第二个整数的排序位次,第二个整数为原待排列的整数。
    对于两个输入文件,即文件A 和文件B ,请编写MapReduce程序,对两个文件进行合并排除其中重复的内容,得到一个新的输出文件C。
    现有以下关系型数据库中的表(见表4-20表4-21和表4-22),要求将具转换为适合Hbase存储的表并插入数据。
  • 原文地址:https://www.cnblogs.com/lightsong/p/5184463.html
Copyright © 2011-2022 走看看