Ruby 1.9 更新 (類別、區塊、例外與列舉)

前篇

  • #instance_methods, #private_instance_methods, #public_instance_methods 現在回傳的是 symbol array 而不是 string array。
  • const_defined?, #const_get and #method_defined? 增加一個參數,決定要不要判斷 include 進來的部份。比方說:
    [code lang="ruby"]
    module A; X = 1; def foo; end end
    module B
    include A
    const_defined? "X" # => true
    method_defined? :foo # => true
    method_defined? :foo, false # => false
    const_get "X" # => 1
    end
    [/code]
  • 新增 class_variable_defined? 方法。
  • class_variable_{set,get} 變成 public methods
  • 新增 attr 為 attr_reader 的 alias
  • Class singleton class:
    [code lang="ruby"]
    class X;end; x=X.new; class << x; self < X; end # => true
    [/code]
  • Class 變數不會繼承。
  • binding evaluation:
    [code lang="ruby"]
    a = 1
    binding.eval('a') # => 1
    [/code]
  • Proc 加入了 yield 方法。
  • arity 方法的定義更改為參數的個數
  • procProc.new 的簡寫。
  • 新增 Proc#lambda? 方法
  • 用 exception 的繼承關係取代掉 StandardError,所以這樣的 code 在 1.9 以後不會被 rescue:
    [code lang="ruby"]
    "".asdas rescue 1
    [/code] (本來會丟到 stderr 上)
  • exceptions 都被視為(比較上)相等的。
  • SystemStackError 改為繼承自 StandardError
  • exception 不再提供 to_str 方法,也就是 $!.to_str 的寫法會有問題。
  • Enum 新增 cycle 方法,用法如下:
    [code lang="ruby"]
    a = ["a", "b", "c"]
    a.cycle {|x| puts x } # print, a, b, c, a, b, c,.. forever.
    [/code]
  • Enumerable#each_with_index 讓原本的 each 方法可以指定從哪個 index 開始。
  • Enumerable#first(n) 傳回前 n 個物件。
  • Enumerable#group_by 以 block 的回傳值來分 group。如:
    [code lang="ruby"]
    (1..10).group_by{|x| x % 3} # => {0=>[3, 6, 9], 1=>[1, 4, 7, 10], 2=>[2, 5, 8]}
    [/code]
  • Enumerable#find_index 根據 block 回傳值來傳回符合的 index:
    [code lang="ruby"]
    (1..10).find_index{|x| x % 5 == 0} # => 4
    (1..10).find_index{|x| x % 25 == 0} # => nil
    [/code]
  • Enumerable#take 若只傳一數字參數,則與 first 方法相同,否則就根據 block 的回傳值。
    [code lang="ruby"]
    a = [1, 2, 3, 4, 5]

    a.take(3) # => [1, 2, 3]
    a.take {|i| i < 3 } # => [1, 2]
    [/code]

  • Enumerable#droptake 方法相反。
  • Enumerator#each 如果沒有傳入 block ,則傳回自己本身。
  • 如果對一個 enumerable 物件沒有指定 block 的話,則執行結果傳回一 Enumerable 物件。
  • Enumerable#inject(reduce) 若沒傳入 block,則以第一個參數為作用的方法,第二個參數(選擇性)為初始值。
  • Enumerable#count 方法,計算 enum 裡有幾個符合 block 或參數條件的物件:
    [code lang="ruby"]
    ["bar", 1, "foo", 2].count(1) # => 1
    ["bar", 1, "foo", 2].count{|x| x.to_i != 0} # => 2
    [/code]
  • Enumerator#with_index 讓 enumerables 在 iterate 時提供 index:
    [code lang="ruby"]
    [1,2,3,4,5,6].map.with_index {|x,i|[2,5].include?(i) ? x : x*2} # => [2, 4, 3, 8, 10, 6]
    [/code]
  • Enumerable##min_by, #max_by 方法找出最小、最大值。
  • Enumerable#zip 方法不再將參數轉型成 array。