Ruby 的聖誕禮物就是版本 1.9 的釋出。
Ruby 在 2007 年的聖誕節釋出了 1.9 的版本,基本上這個版本可以視為 Ruby 2.0 的搶鮮(Preview)或是實驗(Experimental)版本,如果你現在手上有很重要的 RoR 程式在執行,還是先不要把 Ruby 更新會比較好。這裡有完整的 Changelog,如果不想看全文的,就由我這篇拙作來為各位介紹一下 Ruby 1.9 究竟有哪些改變。(這一系列的文章會分別把 Ruby 1.9 的更改逐一介紹完畢。)
- Ruby 1.9 提供了 hash 的新寫法:
[code lang=”ruby”]
{a: “foo”, b: “bar”}
# 本來是 {:a => “foo”, :b => “bar”}
[/code] - 再者,就是當內層區塊使用到與外層區塊相同的變數名稱時(shadow),Ruby 會丟出警告的訊息。另外,區塊(block)所使用的變數一律為 local:
[code lang=”ruby”]
a = 1
10.times{|a| a=2} # !> shadowing outer local variable – a
a # => 1
[/code] - 新的 lambda 語法:
[code lang=”ruby”]
a = ->(b,c){ b + c }
a.call(1,2) # => 3
#也可以拿到括號
-> b, c { b + c }.call(1,2) # => 3
# 或是直接用 .() 取代 .call()
a.(1,2) # => 3
[/code] - 而 block 也可以使用 block 參數(參數名稱前加一
&
)
[code lang=”ruby”]
define_method(:foo){|&b| b.call(bar)}
[/code] - 新的 block 參數,會將原本的
|v|
視為|v,|
,也就是說:
[code lang=”ruby”]
def m; yield 1, 2; end
m{|v| v}
[/code]
在 1.8+ 版本以前,這個例子的v
會讀到[1, 2]
當成是傳入一個 array,不過會有警告訊息(說是參數個數不符),但是在 1.9 以後,這個例子的v
只會接到 1 而忽略掉之後的參數。 - Array 可以被切開來這樣寫:
[code lang=”ruby”]
def foo(*a)
a
end
foo(1, *[2,3], 4, *[5,6]) # => [1, 2, 3, 4, 5, 6]
[/code]
或是:
[code lang=”ruby”]
a = [1,2,3]
b = [4,5,6]
[*a, *b]
[/code]
同時 1.9 也以to_splat
取代了to_a
。
於是,選擇性的參數傳入也可以這樣寫:
[code lang=”ruby”]
def m(a, b=nil, *c, d)
[a,b,c,d]
end
m(1,2) # => [1, nil, [], 2]
[/code] ?a
改為回傳單一字元,而非數字- 在
#[]
裡可以傳入 splat, assoc, 及 block 作為參數:
[code lang=”ruby”]
class Foo; def [](*a, &block); block.call(a) end end
a = (0..3).to_a
Foo.new[*a, :op => :+]{|x| x } # => [0, 1, 2, 3, {:op=>:+}]
[/code] - 像 C 語言中的
printf
格式化輸出字串 (%c
: 單一字元;%u
數字) - 在 ternary (三元) 運算式(如:
x ? a : b
)裡可以在 : 之前斷行 defined?
方法回傳的值不再區分 local-variable 是否 inner-blockBasicObject
的結構:
[code lang=”ruby”]
BasicObject.instance_methods
# => [“__send__”, “__id__”, “==”, “send”, “send!”, “respond_to?”, “equal?”, “object_id”]
Object.ancestors # => [Object, Kernel, BasicObject]
[/code]instance_exec
方法能夠根據指定的self
來執行區塊。send
方法再也不能摸到 private variable 了!require
方法會去讀$"
裡的值作為完整路徑。所以你可以寫這樣:
[code lang=”ruby”]
$” << File.expand_path(loaded_file) require loaded_file [/code]=~
以 nil 取代 false 的回傳值。tap
方法用來作 chain-calling。如:
[code lang=”ruby”]
“F”.tap{|x| x.upcase!}[0] # => “F”
[/code]
上述的例子若寫成 “F”.upcase![0] 則會因為 “F”.upcase! 傳回 nil 而錯誤。- 新增
instance_variable_defined?
,define_singleton_method
,singleton_methods
方法。
第一個hash新語法1.9被標上Ruby2,這次1.9更新會列入嗎
[quote comment=””]第一個hash新語法1.9被標上Ruby2,這次1.9更新會列入嗎[/quote]
Ruby 1.9 應該就是 Ruby 2.0 的 development release。
而且剛才 build 好 Ruby 1.9 了,的確可以 work.
只是 p 出來的結果還是用
{:a => "foo", :b => "bar"}