2007年3月28日星期三

从 门徒 到 训练日

这个标题我想了好久,今天终于写上去了。

两部电影都有惊人的相似。
两种叙事手法,两个不同国度,同一个故事。
让我感触多多。
故事背景:毒品。
黑道版:《门徒》
师父和徒弟的故事,

待续......

白道版:《训练日》
上司和下属的故事,

待续.......

2007年3月18日星期日

街头体验了一把黑市T43

今天无事一个人在延安路上逛街。
我先去庆春路新华书店转了转,出来过天桥,有一人向我使眼神,
他靠近说了声“电脑要不要?”我没搭理他,接着一直走,
我来到银泰,据说同事在这儿做市场调查,我特意来观摩一下,从银泰一楼逛到8楼,没发现同事踪迹。
无趣的我又想起了刚才那个兜售电脑的,平时街上见是见多了,但没体验过。心想也许正一台崭新的T60等着我在,价格还便宜着,一般都是骗子,我还决定体验一把。
我故意走到刚才下天桥的位置,那人好像事先约好一样的迎了上来。
我问:“你卖什么电脑?”
他说:“笔记本”,还一阵微笑,貌似要让我这次捡个打便宜似的
我问:“啥牌子的?”
他用夹生的普通话念出了3个估计他一辈子都不知道含义的字母:“I B M”
我顿时眼睛一亮,忙道:“看看”
他很神秘的问了我一句:“你是不是确定想买?”当时我就断定他是个SB!^_^
我很高调的说道:“废话,不买我站大街上跟你搭个啥话,你的电脑在哪?”
他好像早有准备的带我去了街边:“就在这里看一下吧”
他从身上那个不起眼的×货NB包里掏出了眼熟的小黑,
可还没打开,我就觉得不对,因为事先他没报型号。我从屏幕接口发现和T23一样(头天我还用了一下同事的T23)有金属的方形结合位。而是和底板连在一起的宽宽的黑色接口。
他一打开,居然屏幕就亮了,没关机。屏幕下发赫赫的写着“T43 ” 。我心想,还不错类,如果便宜,可以买个先玩玩。
我仔细一看,键盘是英文+日文的。感觉奇怪的。他很熟练的打开我的电脑属性给我看,我一看迅驰一代2G,512M内存。看来是高配了。
他没让我多点一下,就关上了本本,放进了包包。
我没多想就问价格,他MD就是不说多少钱,问我是不是一定要买。
我一下火了,就说:“你不说价我怎么买,便宜的话我当玩具买个回去,贵了就算了。”,
他一下急了:“就开口3600”。
我说:“你这东西成色太久,而且型号都是两年前的货,放外边一分钱不值”
他说:“这个、、、、这个我也不太清楚,我不懂电脑,反正这个绝对好东西”
我说:“如果配件齐全,质量没问题,我最多出2000。”
他说:“那卖不起,你再加点”
当时我拿还有耐心扯这么多,心想即便是堆垃圾,2000也可以接受了
我让他再次拿出看看,这次我想看的是显卡。
他小心翼翼的拿出来,这次让我来操作:“我直入主题,打开设备管理器,显示卡。”
“ATI9600 128M”我靠,这么牛的配置,如果2000拿下,应该可以了。
他一见我的表情就知道我是想买了,便告诉我,如果想要可以便宜点,2800给我
虽然当时我还比较理智,
平时一直关注小黑,对小黑的配置都还算比较了解,基本都能背出来,
但这个时候又点迷糊了,毕竟一台可以开机正常运行而且高配的T43就在眼前,
我灵机一动,就跟他说:“现金我给你2000,你拿钱走人”
他说:“那不行,最低我再让点,2600”
我说:“如果你非要2600,也可以,我只能给你转帐”
他一下傻了:“怎么个转帐啊,你啥卡啊”
我说:“信用卡,提现手续费太高”
说着说着,我就一直向前走,他一直跟着旁边,几番下来他也不想让,我就说:“你不卖就走人”
他很自觉的停了下来,默默的看着我那高大的背影渐渐的远去,留下的却是他那台不知所云的T43。
我马上一个短信发给了上海一朋友,写道:“黑货,T43,ati9600,512RAM,2000块,如何?”
他小子还真回复的很及时,不到1分钟短信就发了过来:“T43没有听说ati9600的显卡”
妈的,我看完后头冒了一下汗,差点被忽悠了。这时才意识到T43是X300和X700的显卡。
回头再看看,那SB还站在离我三十米的地方向我挥挥手。操

这里我总结了一下我的体验 :
1、不要贪小便宜,虽然我当时也是怀着去体验一下的心态,但真正看到的时候,还是容易失去理智。
2、平时一定要熟背各代小黑配置清单及外观,这样才能以不变应万变,手动心不动。
3、平时逛街,身上一定不要带太多现金,最好钱包,卡也不带。我是老婆不在身边,一个人无所谓了,呵呵
4、小黑还是要到信誉好的X货商买(星星应该不错),二手看都不要看,90%都是拼装起来的,各位可以去淘宝搜一下,几十个本本堆地上,暴汗。

2007年3月14日星期三

The Ruby Way

Ruby是一个敏捷的语言。它是”有延展性的( malleable )”
Ruby是一门解释性语言。当然,这可能是一个Ruby编译器最迟实现的原因,但我们认为,不仅快速成型,而且缩短整体开发周期
Ruby是一门表达对象语言。
Ruby是一门高级语言。

这是同事翻译的《Ruby Way》的第一段,可能语句还比较粗糙,但让人未见其面,先闻其声,真真切切的感受到了Ruby的强大和魅力。

说到Ruby,早在去年,我们团队就着手寻求一种高效,精炼,卓越的语言及框架。半年的时间全献给了PHP,直到接近年末由老唐最终决定还是用了Ruby,及 Rails框架。之前最成功的案例之一就是37signals,这也让我们看到的希望。马上我们就开始了Ruby的学习,几乎所有关于Ruby的资料我们都有,《Ruby way 2nd Edition 》就是其中的一本,幸运的是在不到2周的时间内我们自己翻译成了中文版。我真佩服抗战在第一线的翻译同志们,我深知翻译的痛苦,所以向你们致敬^_^,再整理一下,可以出版发行了。

来说正题,Ruby生来就个性十足的,可以用牛气冲天来形容。下面简单点的举两个例子,呵呵

这一个例子中,第一个程序总是Hello, world! 但在这里,让我们用高级一点的程序开始。这里是一个基于华氏度和摄氏度转换的例子:
print "Please enter a temperature and scale (C or F): "
str = gets
exit if str.nil? or str.empty?
str.chomp!
temp, scale = str.split(" ")

abort "#{temp} is not a valid number." if temp !~ /-?\d+/

temp = temp.to_f
case scale
when "C", "c"
f = 1.8*temp + 32
when "F", "f"
c = (5.0/9.0)*(temp-32)
else
abort "Must specify C or F."
end

if f.nil?
print "#{c} degrees C\n"
else
print "#{f} degrees F\n"
end

运行程序的例子:
Please enter a temperature and scale (C or F): 98.6 F
37.0 degrees C

Please enter a temperature and scale (C or F): 100 C
212.0 degrees F

Please enter a temperature and scale (C or F): 92 G
Must specify C or F.

Please enter a temperature and scale (C or F): junk F
junk is not a valid number.
第一个print语句,实际上是调用Kernel的print方法,写到标准输出设备上。
随后,我们调用gets(从标准输入设备上获取字符串), 赋值给变量str,然后作chomp!去掉尾部的换行。
出现的“标准”函数调用,像print和gets实际上都是Object的方法(原始在Kernel)。同样的方式, chop是一个带有str接收参数的方法。Ruby的方法调用通常可以省略圆括号; print “foo” 和 print(“foo”)是等价的。
变量str是一个字符串,但它不能用其他类型代替。在Ruby中,数据有类型,但变量没有。不存在“声明变量”.
调用exit方法终止程序。同行有个控制结构叫if修饰符。它像大多语言存在的if语句,但它放在了语句的后面; 在此后没有else语句,也没有结束修饰符。作为条件,我们检测两件事情:str有一个确定的值(非nil),是不是空串?
同样的语句也可以这样写:
exit if not str or not str[0]
这样写的原因是一个变量有一个nil值,在Ruby中nil是false。事实上,nil和false都是false,其他都为true。特别要注意的是,空串””和数值0不是false。
接下来在字符串上执行一个chomp!(去掉尾部换行)。
下一语句是多个赋值。Split方法使用空格分割字符串成一个数组,右边分割后的结果赋值给左边的两个变量。
随后的if语句使用简单的正则表达式确定是否为有效数字; 匹配一位或多位数字,如果匹配失败,就是一个无效的数字,程序终止。if语句以end关键字结束; 虽然在这不需要,在end前有else。关键字then是可选的; 在这本书中我们不使用它。
To_f方法将字符串转换为浮点数据。实际上,我们将这个浮点数赋给自身变量temp。
Case语句有三个条件,分别是C、F或无效单位。前面两个是计算; 第三个打印错误并终止程序。
在这个例子普遍可以看出Ruby的case语句。在数据类型上没有限制,表达式也是任意的,甚至可能是一个范围或一个正则表达式。
关于计算没什么神秘的。但考虑到变量c和f涉及到case的分支。实际上这些变量只能有一个是有效的。


让我们在控制结构上花点时间。我们已经看到了简单的例子,if语句和if 修饰符; 还有基于unlesselse也是可选的)的关键字结构, if unless是相反的。

Table 1.1. Conditional Statements

"if" Form

"unless" Form

if x <>

statement1

end

unless x >= 5 then

statement1

end

if x <>

statement1

else

statement2

end

unless x <>

statement2

else

statement1

end

statement1 if y == 3

statement1 unless y != 3

x = if a>0 then b else c end

x = unless a<=0 then c else b end

Ruby中的case语句比大多数语言都强大。这个多分支甚至能测试条件,例如,一个匹配模式。Case语句的这个测试对应运算符(= = =),让我们看这个例子:

case "This is a character string."
  when "some value"
    puts "Branch 1"
  when "some other value"
    puts "Branch 2"
  when /char/
    puts "Branch 3"
  else
    puts "Branch 4"
end

上面的代码输出第三个分支。为什么呢?首先尝试检测”some value””some other value”; 这个失败,因此继续,第三个测试是一个模式; 匹配模式,所以成功,第三个print执行。当所有的case都不成功,执行else

如果测试表达式是一个整型,比较值是个整型范围(如:3.8)。在这种情况下,表达式在这个范围内测试。在所有的实例中,总是执行满足条件的第一个分支。



至于循环机制,Ruby有很多种。wileuntil控制结构是两个预测试的循环。

在表1.2的例子中,假设一个叫list的数组,定义:list = %w[alpha bravo Charlie delta echo]; 遍历数组的每个元素。

Table 1. Looping Constructs

# Loop 1 (while)

i=0

while i <>

print "#{list[i]} "

i += 1

end

# Loop 2 (until)

i=0

until i == list.size do

print "#{list[i]} "

i += 1

end

# Loop 3 (for)

for x in list do

print "#{x} "

end

# Loop 4 ('each' iterator)

list.each do |x|

print "#{x} "

end

# Loop 5 ('loop' method)

i=0

n=list.size-1

loop do

print "#{list[i]} "

i += 1

break if i > n

end

# Loop 6 ('loop' method)

i=0

n=list.size-1

loop do

print "#{list[i]} "

i += 1

break unless i <= n

end

# Loop 7 ('times' iterator)

n=list.size

n.times do |i|

print "#{list[i]} "

end

# Loop 8 ('upto' iterator)

n=list.size-1

0.upto(n) do |i|

print "#{list[i]} "

end

# Loop 9 (for)

n=list.size-1

for

i in 0..n do

print "#{list[i]} "

end

# Loop 10 ('each_index')

list.each_index do |xt

print "#{list[x]} "

end

让我们测试一下细节。循环12都是whileuntil的“标准”循环; 他们本质上是相同的,但它们的条件是互补的。循环34也是一样的。

在前面的例子中,我们没有强调whileuntil循环的修饰符。其实这也是很很用的,它们很简明。下面的例子,两者是等价的:

perform_task() until finished

perform_task() while not finished

在表1.2忽略了一个重大的事情:循环并不总是从开始运行到结束的,中间可能会迭代,或是终止循环。我们需要控制循环。

第一种方式是关键字break, 如上面的循环56.使用它跳出循环;在嵌套循环的情况下,只跳出它所在的循环。

关键字retry有两方面迭代上下文和begin end块的上下文。在任何迭代内容里(或for循环)

关键字redoretry的广义。对于whiletuntil循环作为retry的迭代

关键字next是跳出内层循环

Ruby中,我们已经看到迭代器很重要,我们所未看到的是Ruby语言允许用户定义迭代器添加到预定义。

对于任何对象默认的迭代器是each。这就足够了,因为它允许for循环使用。但迭代器可能给定不同的名字和不同的用途

一个例子,多用途的迭代器。

def repeat(condition)

yield

retry if not condition

end

在这个例子中,当调用迭代器时,关键字yield调用块

j=0
repeat (j >= 10) do
  j+=1
  puts j
end

也有可能通过yield传递参数,作为块的参数列表。有些例子,下面的迭代器只生成整数110,迭代器的调用生成10个数的立方:

def my_sequence

for i in 1..10 do

yield i

end

end

my_sequence {|x| puts x**3 }

2007年3月8日星期四

我在淘宝定的衣架到了,哈哈

同事帮我定的一个,209RMB。自己拼装的。稍后上图,哈哈哈
装到了夜里12点多总算上完了最后一颗螺丝,晕忽忽

2007年3月4日星期日

今天吃什么?

我不知道...

强大的RSS抓取机器人:此乃私人博客 ,非请勿定阅!!!