Ruby conventions

A very useful memo for ruby newbie like me, referenced from here (comments are good too) 

Ruby有不少惯用法,这里略作一些介绍,也方便阅读他人代码:
迭代
一般写法:

for i in (1..10) 
    puts i 
end

习惯写法:

(1..10).each{|i| puts i} 

1.upto(10){|i| puts i} # from njmzhang 

||=赋值
一般写法:

number = 1 if number.nil? 
number = 1 unless number

习惯写法:

number ||= 1

程序入口

if __FILE__ == $0 

if $PROGRAM_NAME == __FILE__

这个相当于main(), 逻辑判断的意思当程序名($0或另一个)和当前文件名(__FILE__)一致时,也就是当前文件是被单独执行的而不是被别的文件调用。这个方法还有个用法是作为unit test使用。
预设变量和特殊记号
类似$0的Perl风格预设常量还有很多,参见Programming Ruby p319
其中比较常用的如$:代表库搜索路径,修改方法常见有:

$:.unshift('buildscript')  # from gigix 

$: << File.join(File.dirname(__FILE__), 'CurrentClass') 

后一种方法使用了相对路径,因为Ruby的module不要求namespace和文件目录结构要对应一致,很多时候统统放一个目录里
%w格式化命令(from qiezi) 可以少打几个引号

%w{a b c d} #等价 ['a', 'b', 'c', 'd'] 

“(~键下的撇号)用来执行shell外部命令,如:
`help`
inject
一般写法:

result = [] 
(1..10).each{|item| result << item}

习惯写法:

(1..10).inject([]){|array, item| array << item}

inject有点难理解,相当于python的reduce和一些FP里的fold。inject的块变量有两个(这里是array和 item),第二个变量(item)用来枚举被inject的集合(这里是(1..10)这个range), 而第一个变量(array)由inject的参数初始化(这里是[],可选),并在block被反复执行时保持持久(相当于静态变量),而item则在每次枚举时被更新为下一个值。我们再看一下inject的另一种通常用法就会更明白了:求和

(1..10).inject{|sum, item| sum += item} 

这个等于

(1..10).inject(0){|sum, item| sum += item}

也就是块变量sum被初始化成0然后反复迭代执行块的内容,最后返回sum
并行赋值
这个很多人都知道了,比如:

a,b = 0, 1 
a,b = b, a # 交换a,b

当然可以延伸出一些很诡异的变化,不提倡使用阿
还有一个用法是让函数返回“多个结果”(不是多个对象),如:

def test 
  1,2 
end 
x, y = test #x = 1, y = 2 

这个njmzhang说的很对,其实函数返回的是一个array,然后再并行匹配到变量上去。(所以我对多个结果特别加了引号)
这显然是个syntax sugar,你随便用逗号分割几个变量是不会自动组成array的。
注意这种并行匹配当两遍不平衡时会造成的问题:

a,b = [1,2,3] # a = 1, b = 2, 3被丢弃 
a,b,c = [1,2] # a = 1, b = 2, c = nil 被初始化成nil 

*的匹配
一般来说*用于把一个array展开:

a, *b = [1,2,3]  #a = 1, b = [2,3]

类似FP里的x:xs(haskell), x::xs(ocaml), [a | b] (erlang from 布娃娃)
rescue简单用法

begin 
1/0 
rescue 
  puts 'wrong' 
end

可以简化为

1/0 rescue puts 'wrong'

命名参数的默认值
ruby有默认参数,但其实没有所谓keyword argument,而是提供一个syntax sugar用hash模拟。但是怎么像Rails的方法那样同时利用命名参数和默认参数值呢?

def image(opt={}) 
    default_opt = {:height => 25, :width => 10} 
    default_opt.merge! opt #opt中同样key的内容会覆盖default_opt中key的value 
end

精细duck typing控制
duck typing的精神就是行为决定类型,而不是相反
a = []
#不用

if a.kind_of? Array then a << 1 
if a.instance_of? Array then a << 1 

#而用

if a.respond_to? :<< then a << 1

获取metaclass
这也比较常见了,各种动态伎俩的开始

sing = class << self; self; end

符号转换到Proc
一般写法:

(1..10).map{|item| item.succ}

习惯写法:

(1..10).map(&:succ)

map(fun(x))般的FP风格
注意这是Rails特有的,通过ActiveSupport对Symbol插入to_proc方法。
不用Rails怎么办呢?一种办法是借助Ruby Facets库(gem install facets):
require ‘facet/symbol/to_proc‘
Facets库包括大量对Ruby核心类的扩展,是个有趣而又危险的大杂烩,也许我以后会另外再专门介绍一下。


Errono::ECONNABORTED problem of rubygems on Windows

This is the problem I have met in using gem to fetch gems for a long time. I really can’t remember when it started to appear and there seems nothing Google can help with this error. A pain in the ass, and I finally felt that I can’t live with it anymore. Thanks for the dynamic characteristic of Ruby, I can modify the code and see how it is changed. So very quickly, I located the problem by adding few lines to indicate the where gem is running at. It is from NET::HTTP::GET, which is the core lib of Ruby and I finally understand why I cannot find any answer by goggling with the keyword "Errno::ECONNABORTED" 🙂  The solution is quite simple, since this is the core lib, the simplest way is to replace Ruby. After uninstalled the ruby(1.87) shipped with Cygwin to the standard one-click installation of ruby 1.86, everything is OK 🙂


Mac G6 keyboard: the best buy of the year

Although It is truly not a cheap keyboard, I still rank the Mac G6 keyboard purchase the best buy of the year. Frankly, my original motivation is quite naive, I was totally fascinated by its elegant outlook.  I won’t feel embarrassed if being called superficial, because I am just a common person who could become excited because of the beautiful things.  The beautiful things normally cost more, it is a fare transaction to me. Fare transaction, huh? but you said it’s the best buy? Yes, it turns out I got more: the touch of this sliver aluminum board with square buttons is as great as its outlook. The typing is real enjoyment to me: quiet, lightsome and reliable. I can now understand what those guru said: the idea is simple flow out under the fingers, because the smooth touching might sometime fools your feeling as there is no such thing exist. I really, really love my Mac keyboard now.

There are too many criticism on Mac product, mostly because of its price. They are all right because it is the fact, but at the same time, you can interpret all those blames as a kind of desire from those poor guys like me, they hate it because they can’t get it:)