lua package编写

之前因为工作的需要学习了lua,在使用的过程中发现Lua挺好用的,故决定把这门语言好好学习一下。这段时间一直在学习Lua,也一直在使用Lua,但是因为工作忙的关系,都没有时间把这些学习的心得记录下来。趁着现在国庆放假期间,把上个月的学习心得记录一下,方便自己后续的查找与回顾(谁叫自己的记忆力已经大不如前了,有些知识长时间不用,就会生疏了)。

好了,废话不多说,总结的内容大致有如下方面:

1) lua package的编写,会以自己编写的简单的loger模块为例进行介绍;

2) 在lua package的基础上,简单分析一下luabit模块的源码;

3) 用c对lua进行扩展;

4) 简单分析一下lua_epoll模块;

5) userdata

6) 在userdata的基础上,实现一个简单的buffer模块;

7) coroutine

一、 lua package

在开发中,我们经常都会根据功能进行模块划分,然后把该模块提供的方法放在对应的文件中。

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都是比较简单的,并没有什么特别的复杂语法要求。

二、 简单的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‘)
时间: 2024-10-22 12:57:32

lua package编写的相关文章

nginx+lua+kafka 编写 在线日志上报系统

案例一 rewrite_by_lua ' --引入openresty自带的json处理对象 local cjson = require("cjson") local producer = require "resty.kafka.producer" -- 定义kafka broker地址,ip需要和kafka的host.name配置一致 local broker_list = { { host = "192.168.115.28", port =

Windows端安装lua脚本编写工具

官网下载地址:https://code.google.com/archive/p/luaforwindows/downloads 先下载如下vcredist_x86.4053.exe工具,并且先安装https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/luaforwindows/vcredist_x86.4053.exe 第二步下载/LuaForWindows_v5.1.4-46.exe工具

Lua 学习之基础篇七&lt;Lua Module,Package介绍&gt;

Lua 之Module介绍 包管理库提供了从 Lua 中加载模块的基础库. 只有一个导出函数直接放在全局环境中: [require]. 所有其它的部分都导出在表 package 中. require (modname) 加载一个模块. 这个函数首先查找 [package.loaded] 表, 检测 modname 是否被加载过. 如果被加载过,require 返回 package.loaded[modname] 中保存的值. 否则,它会为模块寻找加载器. require 遵循 [package.

nginx+lua+redis实现验证码防采集

之前介绍过在nginx里如何嵌入lua模块,利用nginx+lua可以很好的开发开发nginx的业务逻辑,并且达到高并发的效果. 下面我们就来介绍下利用nginx+lua+redis实现防采集的功能. 现象: 网站在为用户提供服务的同时也在被搜索引擎.采集器不断的抓取,可能会造成网站不堪重负,导致页面放回5XX错误.针对此种情况,我们就要对采集器及搜索引擎来进行访问控制,当然对搜索引擎的控制可能会影响网站的收录. 功能描述: nginx+lua在前端实现客户端的访问控制,将客户端的访问信息记入r

高频访问IP限制 --Openresty(nginx + lua) [反爬虫之旅]

嗯-.本人是从写爬虫开始编程的,不过后面做web写网站去了,好了,最近web要搞反爬虫了,哈哈哈,总算有机会把之以前做爬虫时候见识过的反爬一点点给现在的网站用上了~ 做爬虫的同志,有怪莫怪喽~还有求别打死 > < 首先要提一下AJAX,现在普天下网页几乎都是往特定的数据接口请求数据了,除了什么首屏渲染这种服务端渲染好html以外,几乎没有什么静态网页了.我看了有一些帖子说AJAX让爬虫难做,可是我觉得结合一些工具(比如chrome的开发者工具),找到AJAX所请求的后端数据接口一点也不难,而且

Lua的require和module小结

Lua的require和module小结  module特性是lua5.1中新增的,用于设置Lua文件自己的模块,最常用的方式是module(name,package.seeall),有时候lua文件名和module设置的名字不一样,到底require的时候该 require文件名还是require模块(module)名了,今天自己试了一把  首先,如果在lua文件中不显示的require,那么lua运行环境会默认加载哪些呢? 可以通过遍历package.loaded数组来查看,包括以下  st

LUA+resty 搭建验证码服务器

使用Lua和OpenResty搭建验证码服务器 雨客 2016-04-08 16:38:11 浏览2525 评论0 云数据库Redis版 摘要: Lua下有个Lua-GD图形库,通过简单的Lua语句就能控制.生成图片. 环境说明: 操作系统:RHEL6.4 RHEL系统默认已安装RPM包的Lua-5.1.4,但其只具有Lua基本功能,不提供 lua.h 等,但 Lua-GD 编译需要用到 lua.h,故 Lua 需要编译安装. Lua-GD... Lua下有个Lua-GD图形库,通过简单的Lua

使用Nginx+Lua(OpenResty)开发高性能Web应用

在互联网公司,Nginx可以说是标配组件,但是主要场景还是负载均衡.反向代理.代理缓存.限流等场景:而把Nginx作为一个Web容器使用的还不是那么广泛.Nginx的高性能是大家公认的,而Nginx开发主要是以C/C++模块的形式进行,整体学习和开发成本偏高:如果有一种简单的语言来实现Web应用的开发,那么Nginx绝对是把好的瑞士军刀:目前Nginx团队也开始意识到这个问题,开发了nginxScript:可以在Nginx中使用JavaScript进行动态配置一些变量和动态脚本执行:而目前市面上

自动生成ulua中使用的lua代码

本篇主要解决的问题是使用lua脚本编写unity界面逻辑时,自动生成一些查找控件及绑定事件的lua代码! 现在很多unity项目都是用ulua作为热更新解决方案,因此需要用lua来写相关的逻辑,经常会用到的就是在lua中查找某个对象,尤其是写一些UI逻辑! 比如在Login界面中有登陆按钮.记住密码勾选框,在lua中获取这两个按钮可能的lua代码写法就是: a1 self.loginButton = self.gameObject.transform:findChild('loginRoot/.