分类: lua

  • Lua编程学习及资源

    1,Lua学习用什么书?

    推荐《Lua程序设计》(简称PIL),译者@周惟迪 (搜Weibo),可以在淘宝上搜到卖家。比如 http://item.taobao.com/item.htm?id=13569912375

    也可以在网上搜到中文版文档,另外可以看手册http://www.lua.org/manual/5.1/ 如果新学Lua,可以直接看Lua5.2的手册 http://www.lua.org/manual/5.2/

    2,Lua编程相关博客和网络链接?

    国内一直推Lua的高手只有云风 http://blog.codingnow.com/ 我这里也写了一些Lua相关的普及性内容 http://sunxiunan.com/?cat=21

    推荐Lua学习者必看的网站,http://www.lua.org 是首选,可以下载源代码,书籍;还有邮件列表的链接 http://www.lua.org/lua-l.html 建议大家加入讨论,其中有[ANN]标记的是项目发布通告,另外技术讨论也非常深入;Lua的wiki也值得经常光顾 http://lua-users.org/wiki/ 比如这个FAQ就很有价值 http://lua-users.org/wiki/LuaFaq ,还有一个比较完整版本的FAQ在这里 http://www.luafaq.org/ ,我也有一个中文版的LuaFAQ在这里 http://sunxiunan.com/?p=1515;最后建议大家经常看的网站是github.com,搜索Lua关键字就可以找到很多开源项目。

    3,Lua安装程序?

    Ubuntu以及Debian下安装 http://sunxiunan.com/?p=1529 ,也可以直接用apt-get安装。

    Windows下的安装可以安装http://code.google.com/p/luaforwindows/这个集成安装包,里面的第三方库有些旧,但是一般使用也足够了。

    4,我博客中关于Lua编程的部分文字推荐

    http://sunxiunan.com/?p=2044 Lua的优点以及与Javascript不同之处

    http://sunxiunan.com/?p=1949 Lua和Python协程相关资料

    http://sunxiunan.com/?p=1919 Lua非官方FAQ翻译

    http://sunxiunan.com/?p=1681 Lua Unicode(wiki翻译)

    http://sunxiunan.com/?p=1680 static link luasocket into lua with VC2010 under windows,静态链接Luasocket到Lua可执行程序中

    http://sunxiunan.com/?p=1654 【译文】比较Lua协程与Python生成器

    http://sunxiunan.com/?p=1597 谈新技术学习方法-如何学习一门新技术新编程语言

    http://sunxiunan.com/?p=1503 Lua Wiki 部分翻译 — Lua源代码

    http://sunxiunan.com/?p=1498 How to create c extension for lua and pass complex structure step by step

    http://sunxiunan.com/?p=1447 勿用屠龙来杀猪-论如何正确整合Lua与C++

    http://sunxiunan.com/?p=1358 Lua代码阅读(1),可惜烂尾了

    http://sunxiunan.com/?p=1258 Lua通过COM调用外部程序excel及调用windows api

    5,有趣的Lua开源项目推荐

    第一名当然是LuaJit http://luajit.org/ 最新版本Luajit2.00 beta10,有人把其中的FFI抽取出来做成了单独项目,可以在github上搜到。

    http://openresty.org/ 这是@agentzh 的项目,基于Nginx和lua-module做的一个整合包,如果是新的大并发系统,很大力推荐使用openresty。

    https://github.com/keplerproject/ Lua web开发相关的一个项目,包含不少子项目。其中Luafilesystem和Luarocks很知名!

    https://github.com/stevedonovan/Penlight Penlight是一个对Lua标准库的扩展,有点类似Jquery对于Javascript的作用。

    https://github.com/fab13n/metalua metalua,给Lua加上了强大的元编程能力(metaprogramming),0.5版使用Lua实现,不需要修改Lua代码了!

    https://github.com/antirez/redis redis的2.6版本包含了Lua脚本能力

    https://github.com/kripken/emscripten 可以将Python,Lua通过llvm编译成javascript

    https://github.com/leafo/moonscript 就相当于coffeescript和javascript的关系一样,一种新的语言,可以编译成Lua代码。

    另外有个项目Lua2c可以把lua编译成c,这个比较简单,一搜便有。

    https://github.com/LuaDist/Repository 最新出现的Lua安装器,下载后编译一条龙服务,类似nuget,gem,easy_install这些程序,Windows下也可以使用(mingw)。

    https://github.com/luvit/luvit 仿造node.js,用Lua代码进行高并发编程

    https://github.com/jmckaskill/luaffi 前面说的从luajit抽取的ffi项目

    https://github.com/LuaLanes/lanes Lanes is a lightweight, native, lazy evaluating multithreading library for Lua 5.1

    http://www.lua.inf.puc-rio.br/luagravity/ Lua下的async,await,这个项目应该很好玩,但是我没仔细看过。LuaGravity is a reactive language that implements the synchronous approach for concurrency. It is roughly based on Esterel and FrTime, two synchronous reactive languages, the former having an imperative style, the latter being functional.

    https://github.com/chaoslawful/lua-nginx-module Nginx的Lua模块,openresty的核心部分,其中cosocket是利用协程实现的socket,好处是什么,我也不知道啊(因为服务器端编程实在很少接触)

    总之,

    大家可以到 https://github.com/saga/following 看我watch的项目,其中很大一部分是跟Lua相关的。

     

  • Lua的好和不同 part1

    翻译自 http://notebook.kulchenko.com/programming/lua-good-different-bad-and-ugly-parts

    我已经用Lua编程了9个月,应该是时候停下来想想这段经历了。过去几年用过不少编程语言, perl, C, Javascript, MATLAB还有其他的,从TurboPascal到F#。Lua和这些语言做个比较是件很有意思的事情。我已经用Lua完成了一些不同类型的项目:一个远程调试器MobDebug https://github.com/pkulchenko/MobDebug ,扩展一个Lua IDE https://github.com/pkulchenko/ZeroBraneStudio ,一个mobile应用https://github.com/pkulchenko/LuaRemote ,还有几个教育性质的脚本https://github.com/pkulchenko/ZeroBraneEduPack ,以及一个在浏览器canvas上使用Lua画图的demo http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua 。

    我已经看到有比较Lua好坏的文章,比如(http://lua-users.org/lists/lua-l/2007-11/msg00248.html http://blog.datamules.com/blog/2012/01/30/why-lua/ http://lua-users.org/lists/lua-l/2012-01/msg00731.html http://stackoverflow.com/questions/564665/advantages-of-lua http://gergely.imreh.net/blog/2011/07/language-of-the-month-lua-part-2/ http://stackoverflow.com/questions/1022560/subtle-differences-between-javascript-and-lua http://www.luafaq.org/gotchas.html ),但是我发现一些影响或者比较关注的特性没有在列表上。所以我写一个自己的列表。这篇文章不够广泛,Lua语言的某些方面也没有覆盖到(比如math和string库),但是它已经包含了我用Lua语言的要点。

    Good

    小:20000行源代码https://github.com/LuaDist/lua 在Linux下编译后就是182K左右的可执行解释器。

    可适性:任何有ANSI C编译器的平台都可以编译。可以看到在http://www.eluaproject.net/ 以及Lego Minstorms NXT上 http://hempeldesigngroup.com/lego/pblua/ ,mobile平台https://github.com/divineprog/mobilelua 游戏主机 http://blog.brokenfunction.com/2011/11/how-to-make-a-massively-cross-platform-game/ 到浏览器中(翻译到Javascript)http://notebook.kulchenko.com/programming/drawing-on-browser-canvas-with-lua

    容易嵌入和扩展:http://www.lua.org/pil/24.html 提供了简洁易用的接口与C/C++进行互通。

    快:http://shootout.alioth.debian.org/ 相比其他编程语言性能非常不错,还有一个JIT编译器 http://luajit.org/performance.html 对某些任务下的性能有显著提升;如果这还不能满足某些人,可以使用C语言实现性能瓶颈部分,与C的集成很容易,还可以继续从其它有用的部分收益。

    文档不错:语言手册 http://www.lua.org/manual/ ,书籍http://lua.org/pil/ 还有wiki http://lua-users.org/wiki/ 另外有http://www.capgo.com/Resources/SoftwareDev/LuaShortRef51.pdf

    友好热心的社区 http://lua-users.org/ ,通过文档,wiki还有邮件列表http://www.lua.org/lua-l.html 和SO http://stackoverflow.com/questions/tagged/lua ,任何问题都可以解决。

    干净和简单的参数适合初学者,对于非程序员也容易理解。Lua从Pascal的后继Modula http://en.wikipedia.org/wiki/Modula 借鉴了大部分控制语法,我仍然记得Philippe Kahn快速优雅的Turbo Pascal IDE http://en.wikipedia.org/wiki/Turbo_Pascal

    集成解释器:只要命令行运行lua就行了

    协程http://www.lua.org/pil/9.html 的内在支持,到实现iterators http://www.lua.org/pil/9.3.html 和非抢占性多线程 http://www.lua.org/pil/9.4.html

    增量垃圾收集器http://www.lua.org/manual/5.1/manual.html#2.10 有很低的延迟,没有额外的内存开销,很少的实现复杂度,支持弱表http://www.lua.org/pil/17.html

    强力的混杂式tables http://www.lua.org/pil/2.5.html 可以存储任意类型(除了nil),可以通过任何值索引(除了nil),比如 [1, 2, 5, foo = “bar”, [func] = “something”, [“some spaces”] = value()]

    词法定界(Lexical scoping)

    函数式编程http://www.lua.org/pil/6.html 通过一级(first class function)函数http://www.lua.org/pil/5.html 和闭包实现http://www.lua.org/pil/6.1.html

    尾调用http://www.lua.org/pil/6.3.html : return functioncall()

    递归函数不需要事先声明 local function foo() … foo() … end ,注意这样是不行的local foo = function() … foo() … end

    函数可以返回多值。调用者可以要求任意数量的返回值,如果比实际返回数量少,剩余的被抛弃,如果要求的多于实际返回的,用nil填充。

    函数允许可变函数参数个数 function foo(…) local args = {…}; bar(param, …) end

    Tables可以解开成一个参数列表,通过unpack(或者Lua5.2的table.unpack)实现 print(unpack({1, 2, 3})) prints 1 2 3

    可以操作环境变量(Lua5.1中的getfenv和setfenv,Lua5.2中的_ENV),这允许Lua建立沙箱机制 http://lua-users.org/wiki/SandBoxes

    变量列表赋值local a, b, c = 1, 2, x, y = y, x, or a, b = foo()

    使用[[…]] 做多行字符串,可以用[[…[=[…]=]…]]嵌套,注释如–[[…]]

    分号作为语句分隔符是可选的

    通过metatables重载 http://www.lua.org/manual/5.1/manual.html#2.8

    元编程http://metalua.luaforge.net/ 可以做到获取、修改一个抽象语法树来建立新的DSL

    for语句有两种方式,泛型式和数字式,数字型不光支持整数

    函数调用(function call)语法糖 f’string’, f”string” f[[string]]和 f{table},以及方法调用(method call) obj:m()

    简单但是很有用的调试库 http://www.lua.org/pil/23.html

     

    不同之处

    表和字符串索引从1开始,而不是0

    在table中给一个元素赋值nil,就把这个元素删除了。

    没有整型这个数据类型;number表现为浮点数

    没有类,面向对象机制通过表和函数实现;继承通过元表机制实现 http://www.lua.org/manual/5.1/manual.html#2.8

    方法调用通过object:method(args)实现,这和object.method(object, args)一样,but with object evaluated only once

    nil和false是唯二的假值,0,0.0,”0″和其他的都是真。

    ~=不等符号

    not, or, and关键字用做逻辑运算符

    赋值是语句http://www.lua.org/pil/4.1.html,这意味着不能a=b=1或者 if (a=1) then … end

    没有 a+=1 a++或者近似的方式

    没有continue语句,尽管有一个解释 http://www.luafaq.org/#T1.26 和一些变体,像是repeat break until true在循环内部打断,或者Lua5.2中的goto语句

    没有switch语句

    括号在某些情况下有必要,for example, a = {}; a.field works, but {}.field doesn’t; the latter needs to be specified as ({}).field.

    循环中控制变量默认本地化,loop外边就用不了了

    数值型for中的限制和步进值是被缓存的http://www.lua.org/pil/4.3.4.html  in for i = init(), limit(), step() do ... end all three functions initlimit, andstep are called once before the loop is executed.

    条件语句和其他控制结构不需要括号

    字符串和数字自动转换,但是在等于和不等于比较中不能自动转换。 0 == "0" is false{} ~= 1 is true . foo[“0”]和foo[0]在表中指向不同的值; other relational operators generate errors on comparing values of different types.

    逗号和分号可以用在table语法中;都可以放在最后的大括号前面作为可选操作符a = {a = 1, b = 2, }。

    一些组件额外提供;一些人认为这是“没有电池”。这是紧凑和可适内核的结果,也可以通过Luarocks和Penlight解决 http://luarocks.org/ http://stevedonovan.github.com/Penlight/

  • 不同系统(C#/Python/IronPython/Jython/C++)之间的技术整合(续一)

    上一次讨论http://sunxiunan.com/?p=1854 发出去以后提问者回复了一些问题,然后也提出一些新问题,觉得这种总体设计还是挺有趣的,值得发出来一起看看。

        首先说明下为什么会有这样的想法吧—-公司里面有很多不同部门, 部门之间有不同的产品, 对于不同的产品和项目都有着自己的测试方案, 有手工的也有自动化的, 自动化的里面又有使用各种语言的(包括Tcl, Python, Lua等), 即使使用同一种语言, 也有使用各种框架的, 这样就导致了不同产品间很难沟通(最典型的案例就是需要互相借人的时候, 发现要重新学习一套测试方式, 周期太长), 同时也不便于管理. 于是呢, 领导们就突发奇想, 是不是可以统一一种语言和框架呢?为了能满足领导们以及测试部门等各方面的诉求,就有了以上的想法…..

        再来说说我的想法吧. 目前领导要统一已经是一个不可避免的问题了, 因此我非常希望可以引导到Python上面来(其实有些部门是使用Python的), 这里大概和我的个人喜好, 同时我也相信Python可以胜任这种情况. 于是为了证明这个, 所以我就有了以上的尝试. 所有的一切都是为了尽量少改动现有的代码而实现新的统一的目标,想调用Java的原因是有大量的类库目前可以使用,希望调用C/C++的原因是因为其他部门非常有可能需要与硬件相关的C/C++的扩展来实现框架,要尽量满足大家的需求大家才会支持你 。。。。。。

        至于框架方面,说实话,现在Python的测试框架好像还没有特别成熟的,相对来说见得多的是Robot Framework,不过其实我自己的构想是重新创建的一个可以将各个部门完全分离同时又可以分别集群的架构,不过这些都是后话了。

    至于这位仁兄说的这条:

    3)IronPython无法调用C扩展,但是很容易调用C#,可以考虑将其作为C#与CPython的包装层,仅此而已,不要用的太多。
    4)Jython也是一样,仅用于Java与CPython的包装。

    鉴于我才疏学浅,不大理解具体怎么做,因为我的理解是Jython和IronPython都是重新实现的解释器,如何去包装CPython呢?(类似Pyhon For .net的做法?如果是这样的话,这个难度还是相当大的。。。。)

    希望能进一步解释。

    ============================

    我的回答如下:

    包装层(wrapper)是一个抽象概念,有句名言说:编程问题大多数可以通过引入新的抽象来解决(当然,同时也产生新的问题)。

    我们以IronPython和CPython以及现有的C# DotNet程序、C++程序为例来做个探讨好了。在上一次讨论提问者描述以后,我的感觉就是他对性能要求不高,交互紧密性要求不高(也就是未必有IronPython必须不得不直接调用C编写的Python扩展要求),只要把异构系统整合起来能够互相通讯就好。

    整合异构系统,需要分清主次,我这里的设计方案,是以CPython为主,其它编程语言的应用程序或者以DLL形式存在或者被CPython程序调用激活,或者是驻留系统中等待CPython主程序的消息。如果你的方案不是这样,建议你重新考虑一下,没有主次之分的系统设计是有问题的。

    另外看这位提问者的描述,他对于系统之间传递的内容,以及交互的紧密程度,要求不是很高,甚至感觉上就是只要Python能调用一下这些系统就行了。

    这也是设计者需要考虑的,真正需要整合起来做什么,把方案做得细致一些,多考虑一些。

     

    类似这种不同语言的系统进行通讯,基本上有这样几个办法:

    1,基于消息Message Queue通讯

    定义通用格式消息或者使用通用现成格式(比如ProtocolBuffer、Thrift、Json、XML、MsgPack等等),使用跨开发平台通讯方式比如zeromq、http web service进行通讯支持。这是扩展性最好、实现也不麻烦的解决方案,在Python-cn中Zoom.Quiet也提出同一种方案。

    http://en.wikipedia.org/wiki/%C3%98MQ

    http://nichol.as/zeromq-an-introduction

    关于数据序列化比较,可以参考这里

    http://en.wikipedia.org/wiki/Comparison_of_data_serialization_formats

    另外在Windows下,如果是本机,也可以通过Windows自定义消息在不同系统之间传递。

    Python、IronPython也好,C#也好,或者是C++、Lua、Java,它们都很容易建立Web Server,这种方案可以优先考虑。而且scalablity比较好,容易扩展。

     

    2,基于COM

    这个对开发者要求比较高,另外只能用于IronPython和Python以及C++之间,不能用于Jython和Java。但是如果不需要考虑Java系产品,可以考虑COM,其实COM技术即使在DotNet发展到4.0的现在,依然有强大的生命力。而且开发其实也不难。

     

    3,基于数据库或文件系统传递

    这种方案也是比较通用的,如果你不需要序列化对象,只关心结果(比如数字、字符串、时间等等),这个方案也可以参考。优点是相比第一种,更容易学习使用。可以使用SQLite这样轻量的数据库。

     

    4,基于Python序列化传递对象

    这是针对Python编程语言特定的办法。同时也回答了这个问题:怎么叫用IronPython作CPython和C#之间的包装器?

    如果了解Python,应该知道Python有个序列化方法pickle,可以把对象保存到文件中,以后载入。

    幸运的是,经过我的实验,IronPython2.7支持pickle,与CPython之间通过pickle文件传递对象,那是非常容易。

    也就是说,C#程序运行完毕,或者通过IronPython运行完毕,可以将结果保存到pickle文件中,CPython载入以后继续运行,装得跟直接一样。

    通过我的描述可以看出,IronPython和CPython还是没关联,你是你我是我。这的确没办法,因为它们各自都是完整的系统,设计初衷也没考虑到直接交互,但是IronPython发展前景不错,值得跟进。相比Python.Net而言,我还是建议使用CPython和IronPython。

    iron_cpython

     

    最后要说的是,这种大一统的方案,如果没有强力领导介入和长期支持,基本上不能成功。但这不是技术方案需要考量的。

  • Lua cheat sheet

    lua_cheat_sheet

    http://coffeeghost.net/images/lua_cheat_sheet.png

    做一些简单说明。

    关于所有数字都是double,在《programming in lua》第二版中有详细说明。除了极少数情况,可以满足大部分数值计算的需求。

    对于table的说明比较详细。但是对于一些高阶问题没有涉及。比如协程,算是Lua的一大特色。还有函数作为first-class value,也可以做出很多有意思的东西。另外还有meta-table,是Lua模拟OO的关键。另外限于篇幅C API也没有介绍,相比其它编程语言,Lua与C的配合几乎可以说是无缝的。

    相比而言,维基百科上对于Lua的介绍更为全面,而且篇幅也不长。感兴趣的可以参考这个链接作为补充 http://en.wikipedia.org/wiki/Lua_%28programming_language%29

  • lua用于web开发的服务器配置

    有两种方式,一种是apache2.3以上会内置的lua module,大家可以下载apache httpd 2.3.8的代码,在modules目录下有lua这个目录。

    另外一种是今天要介绍的,使用wsapi方式。

    我们使用ubuntu服务器,先确保lua5.14以及apache2都安装成功。

    然后

    sudo apt-get install apache2-mpm-worker liblua5.1-0-dev luarocks

    sudo apt-get install libfcgi-dev libapache2-mod-fcgid

    sudo luarocks install wsapi-fcgi

    然后修改.htaccess或者httpd.conf或者你的vhost配置,添加下面部分。

    Options ExecCGI
    AddHandler fcgid-script .lua
    FCGIWrapper /usr/local/lib/luarocks/bin/wsapi.fcgi .lua

    要注意的是wsapi.fcgi也许是在不同目录下,用find自己找吧。

    在var/www下你的站点中新建一个luacgi目录,然后建立两个文件。

    launcher.fcgi:

    #!/usr/bin/env lua

    require "wsapi.fastcgi"
    require "hello"
    wsapi.fastcgi.run(hello.run)

    index.lua:

    module(…, package.seeall)

    function run(wsapi_env)
      local headers = { ["Content-type"] = "text/html" }

      local function hello_text()
        coroutine.yield("<html><body>")
        coroutine.yield("<p>Hello Wsapi!</p>")
        coroutine.yield("<p>PATH_INFO: " .. wsapi_env.PATH_INFO .. "</p>")
        coroutine.yield("<p>SCRIPT_NAME: " .. wsapi_env.SCRIPT_NAME .. "</p>")
        coroutine.yield("</body></html>")
      end

      return 200, headers, coroutine.wrap(hello_text)
    end

    然后用chown –R www-data:www-data luacgi修改目录owner。

    这时候应该就能用xxx.com/luacgi/index.lua访问了。

    如果你用nginx,也有现成的lua mod可以使用(作者是淘宝的程序员),这里就不多说了。