Lua--模块与包,最佳实践

最近在学Lua 一直对模块与包的使用有很多不明白的地方,有的引用使用. 有的引用使用: 到底都是怎么个情况呢?今天下午要搞定!

一个包就是模块的集合:A Package is a collection of modules.

 从Lua 5.1开始,可以使用require和module函数来分别引用和创建Lua中的模块,

调用模块内函数的简单方法:

require "mod"
mod.foo()
如果模块名太长,可以设置一个local变量

local m = require "mod"
m.foo()
还可以重命名模块内的函数:
require "mod"
local f = mod.foo
f()
由于模块的概念基于一个Table,创建模块时要设置好模块名,声明模块M等操作,如下:

复制代码
 1 --将模块名设置为require的参数,这样今后重命名模块时,只需重命名文件名即可。
 2 local modname = ...
 3 local M = {}
 4 _G[modname] = M
 5 
 6 M.i = {r = 0, i = 1}  --定义一个模块内的常量。
 7 function M.new(r,i) return {r = r, i = i} end
 8 function M.add(c1,c2) 
 9     return M.new(c1.r + c2.r,c1.i + c2.i)
10 end
11 
12 function M.sub(c1,c2)
13     return M.new(c1.r - c2.r,c1.i - c2.i)
14 end
15 --返回和模块对应的table。
16 return M
复制代码

   但上面的这种太复杂和重复,所以要在5.1后,引入了一个module函数用来封装以上基本功能,在文件开头加入module(..., package.seeall) 就可以达到将当前的lua文件声明为一个module,不需要声明当前的module名字。

子module,使用. 来区分名字的level,如一个模块名为mod.sub就是一个mod的子模块,一个包package是所有模块的完全树。

至于什么时候用. 还是: 的问题

function Account.withdraw (self, v)
      self.balance = self.balance - v
end

调用上面这个方法时:

a1 = Account; Account = nil
...
a1.withdraw(a1, 100.00) -- OK
或不带self的方式:
function Account:withdraw (v)
    self.balance = self.balance - v
end
调用时使用:
a:withdraw(100.00)

关于LuaModule使用的最佳实践:在module创建时定义好被引用的名字, 注意require "test22" 和 require ("test22") 即是否加() 功能都是一样的 

// in the main.lua file
require "logging.test"
require "test22"

local function main()
    print("OOLL")
    basi.beforePrint()
    see.beforePrint()
end

//logging.test.lua, logging是一个文件夹
module('basi', package.seeall)

function beforePrint()
    print("IOK")
end

//test2.lua 这个文件和main.lua是位于同一个文件夹下面
module('see', package.seeall)

function beforePrint()
    print("insss")
end
输出结果:

OOLL
IOK
insss



http://www.cnblogs.com/stephen-liu74/archive/2012/07/04/2421283.html    Step By Step(Lua模块与包)

http://www.cnblogs.com/stephen-liu74/archive/2012/07/06/2421656.html    Step By Step(Lua面向对象)


下面的程序的功能有打印一个Lua的Table,和使用扩展参数...时,作为一个整体使用时要使用()

local cacheTb={zhu='1',am1=2, name='oo',kongkong=false}

local function main()

   tb1={dang='lo'}
   backupTb={tian='pp'}
   
   UpdateV(tb1,backupTb)
   
   for i=1,#backupTb do -- 此种打印不出任何结果,如果没有key是数字,这里的i就是key
        print(backupTb[i])
   end  
   
   for k,v in pairs(backupTb) do
        print("key="..tostring(k)..",value="..v)
   end
   
end

function UpdateV(tb1,...)
      if not tb1 then
         return
      end
      for k,v in pairs(tb1) do
        
          if type(k) ~= 'number' and v ~= 'Null' then
               if ... and type(...) == 'table'  then
                    ...[k]=v  -- 注意前面的()不能缺少,否则就会报错
               else
                    cacheTb[k]=v
               end
          end
      end
end

lua table的复制:

function copyTab(st)
    local tab = {}
    for k, v in pairs(st or {}) do
        if type(v) ~= "table" then
            tab[k] = v
        else
            tab[k] = copyTab(v)
        end
    end
    return tab
end

字符串的模式分割:

 t = {}
    s = "from=world, to=Lua"
    for k, v in string.gmatch(s, "(%w+)=(%w+)") do
             t[k]=v
    end
    for k, v in pairs(t) do
         print(k, v)
    end

   beName = "HRS.EIR.EOO.LIST.BeCheckImeiFormatAndType"
   words = {}
   for w in string.gmatch(beName, "[%w_]+%.-") do
      words[#words + 1] = w
      print(w)
   end

输出结果:

HSS
EIR
EIR_LIST
BeCheckImeiFormatAndType


使用LUA反射机制调用执行模块内的function


moTable={}

function execute()

	be=LuaBeModel()
	beName=be:getBeName()
	method=be:getValue("__CALLED_METHOD_NAME",0)[1]
	Util.setBe(be)
	
	-- from the beName get the subDomain Name, and moduleName
	-- use the refelction to invoke the module.method()
	
	modName=nil
	if moTable[beName] == nil then
	    modName = splitBeName(beName)
	end
	
	if modName == nil then
	     return 
	end
	local invokeFunction = loadstring('"'..modName..'.'..method..'"')
    invokeFunction();  
  
    local clearCache = loadstring('"'..modName..'.clearCache()"')
    clearCache();
end


function splitBeName(beName)

   words = {}
   for w in string.gmatch(beName, "[%w_]+%.-") do
      words[#words + 1] = w
   end
   
   subDomainMod='"'..words[3].."."..words[4]..'"'
   print(subDomainMod)
   require (subDomainMod)  -- words[3]: subDomainName, words[4]:moduleName
   moTable[beName]=words[4]
   return words[4]
end

关于上例涉及到的loadstring, 提一下Loadfile 和 loadstring的区别:

loadfile把文件编译为可执行的函数,用f()的形式运行函数,或者loadfile('\\temp\\a.lua')()或者dofile('\\temp\\a.lua')
f=loadfile('\\temp\\a.lua')
print(type(f))
--> function
loadstring用于编译字符串, 常用来实现反射机制,如上。
s=loadstring('a=1+3')
print(type(s))
--> function
运行s()
print(a)
--> 4
或者loadstring('a=1+3')()
用于计算器通常是
str=表达式
st,mg=pcall(loadstring,str)



LuaBind:  LUA Bind中文手册

luaBind 是一个帮助你绑定C++和Lua的库.她有能力暴露 C++ 函数和类到 Lua . 她也有能力支持函数式的定义一个Lua类,而且使之继承自C++或者Lua. Lua类可以覆写从 C++ 基类继承来的虚函数. 她的目标平台是Lua 5.0 ,不能支持Lua 4.0 . 她利用模板原编程技术实现.这意味着,你不需要额外的预处理过程去编译你的工程(编译器会替你完成全部的工作).这还意味着,你也不需要(通常)知道你注册的每一个函数的精确的签名.
因为,LuaBind库会在编译时生成所需的代码.这样做的不利点是,编译时间会随着需要注册的
文件的数目增加而增加.因此建议你把所有的需要注册的东西放到一个cpp文件里面.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 2012 年的时候,我(作者)加入到奇虎 360 公司,为新的产品做技术选型。由于之前一直混迹在 Python 圈子 里面,也接触过 Nginx c 模块的高性能开发,一直想找到一个兼备 Python 快速开发和 Nginx c 模块高性能的产 品。看到 OpenResty 后,有发现新大陆的感觉。 于是我在新产品里面力推 OpenResty ,团队里面几乎没有人支持,经过几轮性能测试,虽然轻松击败所有的其 他方案,但是其他开发人员并不愿意参与到基于 OpenResty 这个“陌生”框架的开发中来。于是我一个人开始 了 OpenResty 之旅,刚开始经历了各种技术挑战,庆幸有详细的文档,以及春哥和邮件列表里面热情的帮 助,我成了团队里面 bug 最少和几乎不用加班的同学。 2014 年,团队进来了一批新鲜血液,他们都很有技术品味,先后都选择 OpenResty 来作为技术方向。我不再 是一个人在战斗,而另外一个新问题摆在团队面前,如何保证大家都能写出高质量的代码,都能对 OpenResty 有深入的了解?知识的沉淀和升华,成为一个迫在眉睫的问题。 我们选择把这几年的一些浅薄甚至可能是错误的实践,通过 Gitbook 的方式公开出来,一方面有利于团队自身的 技术积累,另一方面,也能让更多的高手一起加入,让 OpenResty 的使用变得更加简单,更多的应用到服务端 开发中,毕竟人生苦短,少一些加班,多一些陪家人。 这本书的定位是最佳实践,并不会对 OpenResty 做基础的介绍。想了解基础的同学,请不要看书,而是马上安 装 OpenResty ,把官方网站的 Presentations 浏览和实践几遍。 希望你能 enjoy OpenResty 之旅!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值