Preface
每次呼叫方法時,其實會涉及四個部份:
迭代器與程式區塊
至今看過幾個具有程式區塊的例子。例如 loop 方法:
- loop do
- puts "Orz"
- end
- def forever
- while true
- yield
- end
- end
- forever do
- puts "Orz"
- end
- forever { puts "Orz" }
如果區塊中需要提供額外資訊,則可以定義 區塊參數(Block parameter)。例如:
- def for_with_index(from, to, step)
- i=from
- for i in (from..to).step(step)
- yield(i)
- end
- end
- for_with_index(0, 10, 2) do |index|
- puts index
- end
- class Integer
- def my_times
- for i in 0...self
- yield(i)
- end
- end
- end
- 5.my_times do
- puts "XD"
- end
- 5.my_times do |i|
- puts "#{i} - XD"
- end
- class Array
- def my_reduce(value = 0)
- for i in 0...self.length
- # 不同環境中 self 代表不同對象,在這邊 self 代表陣列實例。
- value = yield(value, self[i])
- end
- value
- end
- end
- puts [1, 2, 3, 4, 5].my_reduce { |sum, value|
- sum + value
- }
- class Integer
- def my_times
- # 不同環境中 self 代表不同對象,在這邊 self 代表 Integer 實例。
- for i in 0...self
- yield(i)
- end
- end
- end
- 5.my_times do |i|
- puts "#{i} - XD"
- if i == 3
- break
- end
- class Integer
- def my_times
- for i in (0..self - 1)
- puts "#{i} - XD"
- if i == 3
- break
- end
- end
- end
- end
但 {} 與 do..end 的寫法,在結合其它方法時,要注意執行順序。例如:
each 執行完會傳回原陣列,因此第一個例子在顯示完 123 後,傳回的陣列被 puts 再分別換行顯示出來。第二個例子則是被照以下順序解釋:
[1, 2, 3].each 會先被執行,然後進行 puts,其實你的區塊是傳給了puts,而不是傳給 each,當你傳遞區塊給一個方法時,而該方法沒有 yield,則傳遞的區塊只是被忽略。
如果你在方法最後一個參數設定 & 開頭的參數,則會使用區塊建立 Proc 物件傳入,你可以用以判斷是否有傳入區塊,或者將代表區塊的物件,再傳給另一方法。例如:
- # encoding: utf-8
- def for_with_index(from, to, step, &block)
- if !block
- return
- end
- for i in (from..to).step(step)
- yield(i)
- end
- end
- for_with_index(0, 10, 2) do |index|
- puts index
- end
- puts "沒有區塊的for_with_index 開始"
- for_with_index(0, 10, 2)
- puts "沒有區塊的for_with_index 結束"
沒有留言:
張貼留言