2010年5月5日星期三

[Note] Programming In Lua 笔记(1): 类型, 值, 表达式, 基本语法

1.
prompt> lua -la -lb
命令首先在一个Chunk内先运行a然后运行b。(注意:-l选项会调用require,将会在指定的目录下搜索文件,如果环境变量没有设好,上面的命令可能不能正确运行。)

2.
prompt> lua -i -la -lb
将在一个Chunk内先运行a然后运行b,最后直接进入交互模式。
-i选项要求Lua运行指定Chunk后进入交互模式.

3.
在交互模式下加载库:
> dofile("lib1.lua") -- load your library

4.
Lua的变量默认是全局的. 定义局部变量使用local关键字.
--[[
应该尽可能的使用局部变量,有两个好处:
1. 避免命名冲突
2. 访问局部变量的速度比全局变量更快.
--]]

5.
注释:
单行注释:--
多行注释:--[[ --]]

6.
nil是Lua中特殊的类型,他只有一个值:nil;一个全局变量没有被赋值以前默认值为nil;给全局变量赋nil可以删除该变量。类似python中的None.

7.
在控制结构的条件中除了false和nil为假,其他值都为真。所以Lua认为0和空串都是真。

8.
string
用单引号和双引号表示字符串, 多行字符串使用[[...]]

9.
运行时,Lua会自动在string和numbers之间自动进行类型转换,当一个字符串使用算术操作符时,string就会被转成数字。反过来,当Lua期望一个string而碰到数字时,会将数字转成string。
-- 尽量避免自动转换, 避免数字与字符串的混合操作.

10.
".."在Lua中是字符串连接符,当在一个数字后面写".."时,必须加上空格以防止被解释错。

11.
显式将string转成数字可以使用函数tonumber(),如果string不是正确的数字该函数将返回nil。反之,可以调用tostring()将数字转成字符串.

12.
and和or的运算结果不是true和false,而是和它的两个操作数相关。
a and b -- 如果a为false,则返回a,否则返回b
a or b -- 如果a为true,则返回a,否则返回b
-- pretty tricky

13.
一个很实用的技巧:如果x为false或者nil则给x赋初始值v
x = x or v
等价于
if not x then
    x = v
end

14.
C语言中的三元运算符
a ? b : c
在Lua中可以这样实现:
(a and b) or c

15.
not的结果只返回false或者true, 和and/or不同

16.
table是非常强大的一个存在. 它的索引下标"默认"从1开始, 而不是0.
它的元素可以是任何类型, 也可以包含数据成员(如下面的x和y).
a = {x=0, y=0, 'aaa', 'bbb', {1,2}, 123}

可以指定索引(模拟字典):
opnames = {["+"] = "add", ["-"] = "sub", ["*"] = "mul", ["/"] = "div"}

强制下标从0开始:
days = {[0]="Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}

在构造函数中域分隔符逗号(",")可以用分号(";")替代,通常我们使用分号用来分割不同类型的表元素。
{x=10, y=45; "one", "two", "three"}

17.
多个变量同时赋值:
当变量个数和值的个数不一致时,Lua会一直以变量个数为基础采取以下策略:
a. 变量个数 > 值的个数 按变量个数补足nil
b. 变量个数 < 值的个数 多余的值会被忽略 容易引起误解的变量初始化:
a, b, c = 0
print(a,b,c) --> 0 nil nil
容易误解为c=0或者a=b=c=0

-- 尽量保证变量个数和值的个数一致

18.
控制结构语句:
if ... then ... elseif ... then ... else ... end
while ... do ... end
repeat ... until ...
for ... do ... end
for ... in ... do ... end

19.
for语句有两大类:

第一,数值for循环:
for var=exp1,exp2,exp3 do
    loop-part
end
exp1,exp2,exp3分别为初始值,终止值,步进值. exp3默认为1, 此时可省略.
注意: 这三个表达式只会被计算一次,并且是在循环开始前。

第二,范型for循环:
for i,v in ipairs(a) do print(v) end
for k in pairs(t) do print(k) end

20.
Lua语法要求break和return只能出现在block的结尾一句(也就是说:作为chunk的最后一句,或者在end之前,或者else前,或者until前),例如:
local i = 1
while a[i] do
    if a[i] == v then break end
    i = i + 1
end
有时候为了调试或者其他目的需要在block的中间使用return或者break,可以显式的使用do..end来实现:
function foo ()
    return --<< SYNTAX ERROR
    -- 'return' is the last statement in the next block
    do return end -- OK
    ... -- statements not reached
end

[Tips]如何快速打开豆瓣电台精简版

新建书签,地址为:
javascript:if(!window.open('http://douban.fm/radio','radiowin','height=186,width=420,toolbar=no,menubar=no,scrollbars=no,location=no,status=no')){location.href='http://douban.fm/radio'}

ps. 为什么我觉得豆瓣改版改得很失败呢?首先是打开电台比原来要麻烦;其次那个搜索栏不再是全能的了。

2010年4月20日星期二

折腾Hackintosh的小结

[声明]
本文仅仅是作者安装Mac OS X的备忘,作者不对任何因为参考本文安装美国苹果公司发行的系统而导致的后果负责。任何企图追究作者责任的人,你在这里看到的都是幻觉。


参考:
[1] 新手安装指南:一步一步在Windows安装苹果雪豹系统
[2] 放出MBR分区硬盘安装雪豹最新系统10.6.2_10C2234所需破解文件osinstall!
[3] PS2键盘+USB鼠标/PS2鼠标+USB键盘/PS2鼠标+键盘的完美解决!!!


1。下载安装盘,我用的是MAC.OSX.SNOW.LEOPARD.V10.6.2-HOTiSO。现在系统最新版已经是10.6.3了。建议使用原版安装盘吧。
2。在Windows下用PQ调整硬盘,分出来一个8G的逻辑分区(用于放安装盘)。后面留20G的空白空间(用于安装系统),这个空间暂时不需要建立分区。
3。进入cmd,使用宇宙无敌超级强大分区小工具diskpart(说实话Windows下面有这么强大的命令行工具总能让我惊讶万分)在最后这20G空间建立一个分区,并把分区类型ID标为AF。大体过程(声明:仅供参考,不保证回忆的准确性,而且这里所用的参数不一定适合你所用的机器。为了您的资料安全,请自行google diskpart的准确用法。):
diskpart
DISKPART> list disk
DISKPART> select disk 0
DISKPART> create partition primary id=AF
我用的是Windows XP,貌似还不支持set ID这个命令,所以只能在创建分区的时候指定ID。可能Windows 7支持随时修改。
这个步骤的目的是建立一个分区类型为AF的分区,即HFS+(MacOSX所用的文件系统)分区。
4。用“leopard硬盘安装助手”复制安装盘镜像到8G分区。
5。安装“MacDrive”,便于对安装盘进行适当的修改。
6。将“合适”的OSInstall文件覆盖安装盘的/System/Library/PrivateFrameworks /Install.framework/Frameworks/OSInstall.framework/Versions/A/下同名文件
7。安装Bootthink
8。将“必要”kext(内核扩展)文件放到“合适”的文件夹下面。这些“必要”的kext文件一般包括:AppleACPIPS2Nub.kext NullCPUPowerManagement.kext fakesmc.kext PlatformUUID.kext ApplePS2Controller.kext OpenHaltRestart.kext Natit.kext VoodooHDA.kext。当然这个和机器硬件配置是有关的,需要反复地尝试才能知道需要哪些文件。“合适”的文件夹一般是C:/Darwin/System/LibrarySL/Extensions。
9。万事俱备,只差重启。现在重启电脑,进入BIOS,确保硬盘工作模式为AHCI而不是IDE。什么,你的BIOS里面没有这个选项?⋯⋯谢谢阅读本文,欢迎下次再来。
10。现在进入到启动画面后,启动菜单应该多了一个“Bootthink”。进入后应该有个叫做“Mac OS X Install DVD”的选项。如果相信自己RP好的话直接按回车。否则你应该按F8键,然后输入“-x32 -v”,如果是64位机器则输入“-v”即可。
11。如果启动有问题则请阅读参考[1]Troubleshooting一节。如果顺利的话会进入语言选择界面。
12。然后就没啥了,抹盘的时候别把不该抹的抹了就行。记住只抹该抹的。给你讲个故事吧:从前有个人他不会抹盘,然后把电脑送给维修,后来⋯⋯后来你都知道了。
13。安装系统成功后如果有的设备不能用,比如PS2的键盘鼠标,USB存储设备,声卡,显卡,网卡等等,安装合适的驱动(即kext)即可,需要大量的搜索和尝试。
14。如果系统启动不了,比如遇到了“无尽的菊花”,可以使用“-s”参数启动,之后会进入单用户模式。此时文件系统是只读的,如果需要修改文件可以使用此命令挂载分区以进行写操作:
#mount -w /
15。Good Luck!


至于Mac OS X的使用体会有心情再写。

2010年3月15日星期一

正在做的twitter"客户端"的截图

项目主页: http://code.google.com/p/twiterm/
CodeName: Darter

把截图放出来给大家预览一下.
目前只有阅读Home时间线的功能.
欢迎提意见和建议!

From Twitter

2010年2月27日星期六

[Twisted学习笔记] Deferred机制

参考阅读:
[1] Deferred Reference
[2] Deferreds are beautiful! (A Tutorial)


最近在研究Twisted, 其中一个会把像我这样的初学者吓住的概念就是Deferred.

我们知道, Twisted是一个异步(asynchronous)基于事件回调(callback-based)的框架, 而Deferred是实现这一特性的关键之一.

Twisted使用Deferred对象来管理回调函数序列(callback sequence).
具体来说:
1) 通过Deferred对象可以为某个事件增加一个或多个事件处理函数(即回调函数);
2) 多个回调函数构成了函数链(callback chain);
3) 增加回调函数的顺序决定了事件响应的"相对顺序";
4) 增加回调函数的方式决定了回调函数的调用时机.

当Deferred对象的请求得到满足, 添加的第一个callback会被调用, 并且其输出会作为第二个callback的输入, 然后像这样沿着函数链依次传递下去. 如下图所示:

[以下为翻译Deferred Reference中的相关段落]
  • 当请求得到结果后, 如果操作成功, 会通过Deferred.callback(result)传递到Deferred Object; 如果失败则通过Deferred.errback(failure).
  • Deferred Object将结果传递给此前注册的回调函数链, 规则如下:
    • 一个callback的输出总是作为下一个callback的第一个参数, 这样就构成了一个处理器链.
    • 如果一个callback产生异常, 则立即转到下一个errback.
    • 如果errback内部产生了异常, 则转到下一个errback.
    • 如果errback没有产生异常, 或者返回了一个twisted.python.failure.Failure实例, 则回到下一个callback.








上图可能会有些误导性, 我又画了一幅示意图:

deferred

2010年1月18日星期一

[攻略]使命召唤-现代战争2-Special Ops-CHARLIE-Homeland Security

参考:
http://tieba.baidu.com/f?kz=667762334
http://tieba.baidu.com/f?kz=679642109
http://3dmgame.chnren.com/bbs/showtopic-1026140.html

其实不用以上攻略中说得这么麻烦,我是这样过关的(Veteran级):
1. 拿到地雷,然后抓住自动机枪左转90°,跑到餐厅里;
2. 把自动机枪架在柜台后面;
3. 把柜台右前方的另一台自动机枪也架到柜台后面,二者保持一定距离;
4. 把手枪换成柜台上的机枪,从后门跑出餐厅;
5. 在后门口和后门口旁边的墙角放置两个地雷;
6. 往巷子里面跑,躲在网后面的那个柱子后面;
7. 用机枪对准后门,然后就等没有被自动机枪消灭的漏网之鱼吧。

用以上方法可以消灭全部的步兵。步兵被灭之后,可以跑到餐厅里,用火箭弹消灭直升机和装甲车。
这种方法比较简单,不用拼命跑来跑去。但是耗时会长一些。

2010年1月17日星期日

Hello World!

Across the Great Wall we can reach every corner in the world. (越过长城,走向世界)

原来的博客挂掉了,可能是暂时的,不过鉴于某国当前的互联网状况,我还是早做打算,干脆迁到blogspot吧。
虽然blogspot频频被墙奸,但是由于“翻墙”已经逐渐成为某国网民除了上QQ之外的基本技能,而且GReader已经被普遍使用,blogspot是一个还不错的选择。

最近谷歌退出中国的事情闹得沸沸扬扬,不知道最后如何收场。
无论如何,could it be any worse?
亲身经历了中国互联网这一年来的各种闹剧,还有什么无耻的做法不能承受,还有什么无耻的人不能忍受?!
在这里引用一下狄更斯的《双城记》开头的一段话:

这是最好的时代,这是最坏的时代;
这是智慧的时代,这是愚蠢的时代;
这是信仰的时期,这是怀疑的时期;
这是光明的季节,这是黑暗的季节;
这是希望之春,这是失望之冬;
人们面前有着各样事物,人们面前一无所有;
人们正在直登天堂,人们正在直下地狱。

很高兴活在这样一个时代。