{ yeah : 必须哒 } No place to place should record our youth?

22Jul/100

Lua学习笔记六——package

Posted by alacner

lua和其他语言一样,也有模块/包的概念,稍微有点不同的是,默认先从环境变量LUA_PATH中搜索lua文件,如果搜索不到,则从LUA_CPATH中搜索C文件。

对于我来说,时而去改变环境变量,则显得麻烦,并且在另外的环境中部署时还要修改环境变量,则显得不人性化,因此,觉得如下方式增加搜索路径比较好:

--将自定义包路径加入package的搜索路径中。也可以加到环境变量LUA_PATH中
[cc lang="lua"]
local p = "自定义包路径的父目录"
local m_package_path = package.path
package.path = string.format("%s;%s?.lua;%s?/init.lua",
 m_package_path, p, p)
[/cc]
自定义包文件及包加载示例,假如文件结构如下:

蓝色表示文件夹,紫色表示文件

----------test.lua

----------demopackage

---------------------init.lua

---------------------a.lua

这时候,demopackage就是一个包了, 模块demopackage的功能由init.lua文件提供,模块demopackage.a由a.lua文件提供,下面将在test.lua文件中调用demopackage包:
[cc lang="lua"]
--init.lua文件

module(..., package.seeall)
function add(n1, n2)
 return n1 + n2
end

function sub(n1, n2)
 return n1 - n2
end

function div(n1, n2)
 if n2 ~= 0 then
  return n1 / n2
 else
  error("require n2 is not zero")
 end
end

function mul(n1, n2)
 return n1 * n2
end
[/cc]
[cc lang="lua"]
--a.lua

module(..., package.seeall)

function p()
 print "module demopackage.a"
end

function lstostring(ls)
 return "{" .. table.concat(ls, ", ") .. "}"
end
 [/cc]

上面的两个文件中,开头都有这么一行代码module(..., package.seeall),这是为了模块名以文件名命名,还有为了不污染全局变量_G,返回当前模块提供的函数等等。相当于:
[cc lang="lua"]
--将模块名设置为文件名,且加载这个模块

local modname = ...

local M = {}

_G[modname] = M

package.loaded[modname] = M

--引入所需模块

local io = io

local print = print

setfenv(1, M)          --> 设置当前环境变量

--开始实现模块功能

function test()

    print("test")

end
……
[/cc]

调用demo文件
[cc lang="lua"]
--test.lua

--将自定义包路径加入package的搜索路径中。也可以加到环境变量LUA_PATH中
local p = "E:/dep/code/lua/"
local m_package_path = package.path
package.path = string.format("%s;%s?.lua;%s?/init.lua",
 m_package_path, p, p)
--print(package.path)  --> lua文件的搜索路径
--print(package.cpath)  --> lua c文件的搜索路径
require "demopackage"
require "demopackage.a"
print("--------package: demopackage --------------")
for i in pairs(demopackage) do
 print(i, demopackage[i])
end

print("--------package: demopackage.a --------------")
for i in pairs(demopackage.a) do
 print(i, demopackage.a[i])
end
print("---------------demo print--------------")
print( demopackage.add(1, 2) )
print( demopackage.a.lstostring({"first", "second"}) )

print( demopackage.a.p() )
[/cc]

 lua中,用require来加载包,如果想重命名加载的包,可以如下操作:

local t = require "demopackage", 这时候,就可以用t调用demopackage中的功能了。

BTW,lua加载包时,不会加载包中所有的模块,这点是跟其他语言不一样的,这样做应该是为了提高运行速度吧。

转载自:http://blog.csdn.net/hong201/archive/2009/05/09/4163378.aspx

Tagged as: , No Comments
22Jul/100

Lua学习笔记五——metatable

Posted by alacner

metatable是元表的意思,在python中,有meta class,即元类,不管是元表还是元类,都是功能强大的,简单的来说,元类就是类的类,元表就是table的table。

下面看看元表的强大,利用table模拟list的加法操作:

定义列表table
[cclN_lua]
list = {}
list.mt = {}
[cclN_lua]

其中list.mt是用来准备定义list的元表的

定义初始化函数

[cc lang="lua"]
function list.new(ls)
local l_ls = {}
setmetatable(l_ls, list.mt)
for i, v in ipairs(ls) do
l_ls[i] = v
end
return l_ls
end
[/cc]
其中setmetatable(l_ls, list.mt)是设置list的元表

定义list的操作函数
[cc lang="lua"]
function list.add(lhs, rhs)
local ret = list.new{}
for i, v in ipairs(lhs) do
ret[i] = v
end
for i, v in ipairs(rhs) do
ret[table.maxn(ret)+1] = v
end
return ret
end
[/cc]
……

定义list的tostring方法,便于打印出人性化信息
[cc lang="lua"]
function list.tostring(ls)
return "{" .. table.concat(ls, ", ") .. "}"
end
[/cc]
定义list操作,相当于C++中的运算符重载
[cc lang="lua"]
list.mt.__add = list.add
list.mt.__tostring = list.tostring
[/cc]
其中__add,做加法运算,__tostring会被print函数调用。另外还有:

__sub 减法 -

__mul 乘法 *

__div 除法 /

__unm 相反数 -

__mod 取模 %

__pow 乘幂 ^

__concat 连接操作 ..

__len 长度操作 #

__eq 相等 ==

__lt 小于 <

__le 小于等于 <=

不等于、大于、大于等于会用 ==, < , <=转换

__index 访问操作 table[key]

__newindex 赋值操作 table[key] = value

__call 调用操作 a = function xx() -- end  a()

调用示例
[cc lang="lua"]
ls1 = list.new{"a", "b", "c"}
ls2 = list.new{"9", "2009"}

ls3 = ls1 + ls2
print(ls3)
for i, v in ipairs(ls3) do
print(i, v)
end
[/cc]
元表是强大的,因为在你用它之前,它已经被设定过了……

转载自:http://blog.csdn.net/hong201/archive/2009/05/05/4153182.aspx

Tagged as: , No Comments
22Jul/100

Lua学习笔记四——协同程序coroutine

Posted by alacner

lua中的协同程序类似于多线程,但是与多线程还是有点区别的,区别在于协同程序必须必须合作,且同一时刻只有运行一个协同程序。

function p()
 print("Hello World")
end

这是一个简单的示例函数,下面看看协同程序的调用

co = coroutine.create(p)
print(co)    --> thread: 003FBBF0
print(coroutine.status(co))  --> suspended
coroutine.resume(co)   --> Hello World
print(coroutine.status(co))  --> dead

在上面的调用代码中,右边附上了打印输出,第一行是创建一个协同程序,第二行查看协同程序的返回值,第三行查看此时协同程序的状态,处于suspended(挂起)状态,第四行执行协同程序,第五行查看此时协同程序状态,处于dead(死亡)状态。

协同程序有四种状态,suspended(挂起)、running(运行)、dead(死亡)、normal(正常),

当调用coroutine.create后,处于挂起状态

调用coroutine.resume后,处于运行状态,执行完毕后,处于死亡状态

当一个协同程序a调用另一个协同程序b后,a就处于正常状态,b处于运行状态

协同程序传递参数:

co2 = coroutine.create(function(a, b)
        coroutine.yield(a * b, a + b)
    end)
print(coroutine.resume(co2, 2, 2009))

在resume调用中,除第一个值外,其余值都将传给yield,执行后的返回之中,第一个值为Boolean类型,协同程序运行是否正常,其余的值是对应yield的返回值。
转载自:http://blog.csdn.net/hong201/archive/2009/05/05/4151835.aspx

Tagged as: , No Comments
22Jul/100

lua学习笔记三——iterator and closure

Posted by alacner

以代码为主,辅助注释

[cc lang="lua"]
--1.无状态迭代器 
--[[ 
    for <var-list> in <exp-list> do 
        --staff 
    end 
    其中,<exp-list>应该返回3个值:迭代器函数,恒定状态,控制变量 
]] 
 
local function getnext(list, node) 
    if not node then 
        return list 
    else
        return node.next 
    end 
end 
function traverse(list) 
    return getnext, list, nil   -- 返回3个值 
end 
-------------- 
list = nil 
for i=1, 10 do 
    list = {val = i, next = list } 
end 
for node in traverse(list) do 
    print( node.val ) 
end 
 
--2.基于closure的具有状态的迭代器 
local iterator 
function allwords() 
    local state = {line = io.read(), pos = 1 } 
    return iterator, state, nil 
end 
function iterator(state) 
    while state.line do 
        local s, e = string.find(state.line, "%w+", state.pos) 
        if s then 
            state.pos = e+1
            return string.sub(state.line, s, e) 
        else
            state.line = io.read() 
            state.pos = 1
        end 
    end 
    return nil 
end 
-- 使用迭代器 
for word in allwords() do 
    print( word ) 

[/cc]
转载自:http://blog.csdn.net/hong201/archive/2009/05/03/4145068.aspx

22Jul/100

Lua学习笔记二

Posted by alacner

lua的第二篇学习笔记

小程序+输出说明

[cc lang="lua"]
--1. 逻辑比较 >,>=,<,<=, ==, ~= 
print( "---------1----------------") 
print(3.14 ~= math.pi)      --> true 
 
x = x or math.pi            -- 等价于 if not x then x = v end 
print(x) 
 
--2. table 初始化 
 
print( "---------2----------------") 
t1 = { color = "blue", own="ha"; "one", "two", "three", [4] = "four" } 
print(t1.color) 
print(#t1) 
print(t1[1]) 
 
 
--3 循环语句中的局部变量作用域 
print( "---------3----------------") 
repeat 
    local line = math.random(1, 10) 
    print( line ) 
until line >= 8          --> 在循环条件中可以访问局部变量line 
 
--4 table 的遍历 
print( "---------4----------------") 
for i in pairs(t1) do           --> 关联表数组全部打印 
    print(i, t1[i]) 
end 
 
print("----") 
for i, v in ipairs(t1) do       --> 只打印数组 
    print( i, v ) 
end 
 
print("---") 
t2 = { 
    {name = "tafjk", ip = "192.168.8.1"}, 
    {name = "test", ip = "192.168.1.5"}, 
    {name = "my", ip = "192.168.201.1"}, 

 
-- table sort 
 
for i in pairs(t2) do           --> 关联表数组全部打印 
    print(i, t2[i].name, t2[i].ip) 
end 
print( "-" ) 
table.sort(t2, function (obj1,obj2) return (obj1.ip > obj2.ip ) end ) 
for i in pairs(t2) do           --> 关联表数组全部打印 
    print(i, t2[i].name, t2[i].ip) 
end 
 
--5 函数返回值 
--若函数调用时最后一个参数,则会返回所有返回值,否则,只返回一个值 
print( "---------5----------------") 
function foo() 
    return 2009, 1
end 
 
print( foo() )              --> 2009 1
print( ( foo() ) )          --> 2009
x = foo() 
print( x )                  --> 2009
 
x,y,z = foo(), "foo"        --> 2009 foo nil 
print(x, y, z) 
 
print( unpack( { foo() } ) )    --> 2009 1,  unpack接受list参数,并从下标1开始返回 
 
print( string.format("%d-%d-%s", 2009, 1, "lua") )  --> 2009-1-lua

[/cc]
转载自:http://blog.csdn.net/hong201/archive/2009/04/28/4134272.aspx

Tagged as: No Comments
22Jul/100

Lua学习笔记一

Posted by alacner

前段时间有空, 看了一小会lua,现在好像又还给了,脑袋空空,再次翻开lua,记录至此。

[cc lang="lua"]--[[
学习lua,小程序,当作学习而已,程序可能没有什么实际意义
]]

-- 1.Hello world

print( "---------1----------------")
print("Hello world") --> Hello World

-- 2.function define

print( "---------2----------------")
--[[
function fact(n)
if n == 0 then
return 1
else
return n * fact(n-1)
end
end

print( "enter a number:" )
n = io.read( "*number" )
print( fact( n) )

]]

--[[3.lua 共用8种基本类型,分别是nil, boolean, boolean, number, string
userdata, function, thread, table,在条件判断时,nil和 false 为假,其他为真。
使用未定义的变量,不会触发异常,会得到nil值
]]

print( "---------3----------------")
print( type( "Hello World") ) --> string
print( type( 2009 ) ) --> number
print( type( print ) ) --> function
print( type( false ) ) --> boolean
print( type( nil) ) --> nil

--4.数字,字符串有趣的操作

print( "---------4----------------")
print( "10" + 1 ) --> 11,这个结果够雷人,在这里做了算术运算,如果在java中,则是字符串连接操作,结果应该是 101
print( "10" .. 1 ) --> 101,结果是想要的 101,在lua中,是用 .. 做字符串相连操作

hw = "Hello World!"
print ("\"" .. hw .. "\" length: " .. #hw) --> "Hello World!" length: 12

--5. table 关联数组

print( "---------5----------------")
t1 = {}
t1["first"] = 2009
k = "second"
t1[k] = t1.first + 1

print(t1.first)
print(t1.second)

-- 用table来实现线性表
array = {}
for i=1, 10 do
array[i] = i .. " hong"
end

for i=1, #array do
print( array[i] )
end

-- table 大小

print ("the array size: " .. #array) --> the array size: 10
array[2009] = "2009"
print ("the array size: " .. #array) --> the array size: 10
print ("the array size(use table.maxn): " .. table.maxn(array) ) --> the array size(use table.maxn): 2009

--6. 函数式编程
--在lua中,有着函数式编程的特性,当然了,其他语言中也有,如python, erlang等等,本人觉得,在erlang中,函数式编程更是发扬光大了

print( "---------6----------------")
p = print
p(" function programming") --> function programming
[/cc]

转载自:http://blog.csdn.net/hong201/archive/2009/04/26/4127042.aspx

Tagged as: No Comments
22Jul/100

接触lua的协同程序

Posted by alacner

lua中没有真正的多线程,用了协同程序代替,照例来个demo看看,如下:

[cc lang="lua"]#!usr/bin/env lua

function receive(prod)
 local status, value = coroutine.resume(prod)
 return value
end

function send(v)
 coroutine.yield(v)
end

-- product
function producer()
 return coroutine.create(function()
  while true do
   local v =io.read()
   send(v)
  end
 end)
end

--consumer
function consumer(prod)
 while true do
  local x = receive(prod)
  io.write(x, "\n")
 end
end

function filter(prod)
 return coroutine.create(function()
  for line = 1, math.huge do
   local v = receive(prod)
   v = string.format("%5d %s", line, v)
   send(v)
  end
 end)
end

--main 协同程序

p = producer()
f = filter(p)
consumer(f)
[/cc]

就一个生产者--消费装模型,看看就行。
转载自:http://blog.csdn.net/hong201/archive/2009/04/06/4052754.aspx