以前由於工做的須要學習了lua,在使用的過程當中發現Lua挺好用的,故決定把這門語言好好學習一下。這段時間一直在學習Lua,也一直在使用Lua,可是由於工做忙的關係,都沒有時間把這些學習的心得記錄下來。趁着如今國慶放假期間,把上個月的學習心得記錄一下,方便本身後續的查找與回顧(誰叫本身的記憶力已經大不如前了,有些知識長時間不用,就會生疏了)。
函數
好了,廢話很少說,總結的內容大體有以下方面:
學習
1) lua package的編寫,會以本身編寫的簡單的loger模塊爲例進行介紹;
ui
2) 在lua package的基礎上,簡單分析一下luabit模塊的源碼;
this
3) 用c對lua進行擴展;
lua
4) 簡單分析一下lua_epoll模塊;
spa
5) userdata
debug
6) 在userdata的基礎上,實現一個簡單的buffer模塊;
調試
7) coroutine
code
1、 lua packageorm
在開發中,咱們常常都會根據功能進行模塊劃分,而後把該模塊提供的方法放在對應的文件中。
lua package 能夠簡單的認爲就是一個「庫」,對外提供相應的功能方法。
在lua中,每個package都有本身的命名空間,避免了命名衝突。
一般,一個簡單的package以下所示:
#mymodule.lua module(..., package.seell) -- ...表示用當前的文件名做爲package名 local function no_access() -- private function print 'can not access into this function!' end function hello() -- public function return 'hello to mymodule' end return _M
使用mymodule.lua。先來看一下但咱們require mymodule模塊後,lua會將其加入到_G table中,看一下都有什麼內容:
# using mymodule require('mymodule') -- 至關於C語言中的include,或者是Python中的import for k, v in pairs(_G.mymoudle) do print(k, v) end
輸出結果以下:
hello function: 003CBFB0
_M table: 003CBB88
_NAME mymodule
_PACKAGE
能夠看到模塊中只有hello函數,那麼no_access函數呢?由於咱們在定義no_access函數時,前面加上了local,就至關於這個函數是模塊內部的,對外不可見,有點和C中的static相似。
從上路能夠看出編寫一個package,以及使用package都是比較簡單的,並無什麼特別的複雜語法要求。
2、 簡單的loger模塊;
咱們在c語言開發的時候,常常會在log輸出的時候,加行當前所在的函數與行號,如printf("%s()-%d: %s", __func__, __LINE__, "debug info");
我在lua調試中,但願能夠在log輸出時,自動輸出當前的函數名與行號,因此就寫了個簡答的loger模塊,支持定義log級別並進行輸出過濾。若有須要可進行改寫,將log輸出到文件中。
loger模塊中使用了debug.getinfo()方法,如要獲取全部的信息,則使用debug.getinfo(3)
代碼以下:
module(..., package.seeall) --local fd_buf = require('fd_buffer') local function show_debug_info(info) print('source:', info.source) print('what:', info.what) print('func:', info.func) print('nups:', info.nups) print('short_src:', info.short_src) print('name:', info.name) print('currentline:', info.currentline) print('namewhat:', info.namewhat) print('linedefined:', info.linedefined) print('lastlinedefined:', info.lastlinedefined) end local loger_level = {DEBUG = 1, TRACE = 2, INFO = 3, WARN = 4, ERROR = 5, debug = 1, trace = 2, info = 3, warn = 4, error = 5} function new(level, fd, out) local buf = nil --[[ if fd and (fd > 0) then buf = fd_buf.new(fd, fd_buf.FD_BUFFER_WRITE) if not buf then return nil, 'fd_buffer new fail' end end ]] local self = {buf = buf, level = level, out = out} local obj = {} function obj.set_out(out) self.out = out end function obj.set_level(level) self.level = level end function obj.get_level() return self.level end function obj.log(level, str) local d_info = debug.getinfo(3, 'nl') -- local d_info = debug.getinfo(3) d_info.name = d_info.name or 'main' local d_str = string.format('[%s()-%s: %s] %s\n', d_info.name, d_info.currentline, level, str) if self.out > 0 then --show_debug_info(d_info) io.write(d_str) end if self.buf then self.buf:write(d_str) end end function obj.debug(fmt, ...) if loger_level[self.level] <= loger_level['DEBUG'] then return obj.log('DEBUG', string.format(fmt, ...)) end end function obj.trace(fmt, ...) if loger_level[self.level] <= loger_level['TRACE'] then return obj.log('TRACE', string.format(fmt, ...)) end end function obj.info(fmt, ...) if loger_level[self.level] <= loger_level['INFO'] then return obj.log('INFO', string.format(fmt, ...)) end end function obj.warn(fmt, ...) if loger_level[self.level] <= loger_level['WARN'] then return obj.log('WARN', string.format(fmt, ...)) end end function obj.error(fmt, ...) if loger_level[self.level] <= loger_level['ERROR'] then return obj.log('ERROR', string.format(fmt, ...)) end end return obj end return _M
loger模塊的簡單使用:
local loger = require('loger') if not loger then print('require loger module fail') os.exit(-1) end local log = loger.new('DEBUG', nil, 1) if log then print('log.new success') --print(log.getlevel()) else print('log.new fail') end local function test1() log.debug('this is debug info') log.info('this is info level') log.warn('this is warning level') log.info('hello %s', 'lua') log.warn('age %d', 28) log.error('only one string') end log.debug('in global test') print('>>>>>>>>>>>>>>>>>>>>>>') test1() print('done\n')