iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
1
自我挑戰組

毫無基礎學習 Ruby on Rails 的 甘苦心得系列 第 11

DAY11 程式碼區塊(Block)

  • 分享至 

  • xImage
  •  

不知道各位在剛接觸Ruby的時候 常常對於block感到很困惑,奇怪為什麼可以這樣寫? 疑 為什麼這樣寫會出錯?
今天這篇我就以我自己學習的觀念講解關於block

什麼是block?

5.times { puts "Hello, Ruby" }      
#=> 印出 5 次的 Hello Ruby

friends = ["kai", "lin", "ding", "kao"]
friends.each do |friend|
  puts friend                       
#=> 這會把陣列裡的元素一個一個印出來
end

result = 0
array = [2,3,4,5,6]

array.each do |value|
  result = result + value  #從do到end中間算是一個block。
end

result
#=> 20

#=>實際上執行的內容為:
# 由於array數列中有五個值,因此總共會執行五次,帶入不同的值
result = result + 2
result = result + 3
result = result + 4
result = result + 5
result = result + 6

大括號 { ... } 以及 do ... end,在 Ruby 稱之一個程式碼區塊(Block)

Block 不是物件

我們常會說 Ruby 是一款物件化很徹底的程式語言,在 Ruby 什麼東西都是物件…嗯,但其實還是有少數的例外,例如 Block 本身就不是物件。Block 沒有辦法單獨的存在,也沒辦法把它指定給某個變數,我就是在這邊卡住的,要稍微注意一下。

do 與 {} 的差異

什麼時候該用do,什麼時候該用括弧{}呢?在Stackoverflow上有許多相關討論,可以整理為以下邏輯:

如果邏輯簡單,可以用一行來處理,就盡量使用 {}
相對之下,如果邏輯複雜,則以分行寫的方式處理,使用do...end寫法

result = 0
array = [2,3,4,5,6]

array.each do |value|
    result = result + value
end

result

#上面這段程式碼可以改寫成

array.each {|value| result = result + value } 

#這樣程式碼一行就搞定而且又清楚

另外,在Rails當中,如果要處理一整串從資料庫挖出來的資料怎麼做?假如我有一堆個人資料要算平均年齡,可以用以下作法:

hash_array = [{:name => "John", :age => 30},
              {:name => "Peter", :age => 28},
              {:name => "Mary", :age => 32},
             ]
result = 0
hash_array.each {|person| result += person[:age] }
average = result / hash_array.length
# => 30

Rails中其他常使用的block:collect、map

map和collect兩個Ruby內建的method是專門產生數列用的,可針對每一個數值進行計算。在處理hash或object的時候,可以分別設定為key和value,就可以分開處理:

# 用於數列
array = [3,6,9]
array.map {|value| value * 10}
# => [30, 60, 90]

# 用於物件
hash = {:name => "Kai", :age => 27, :phone => "911"}
hash.map {|key, value| value }
# => ["Kai", 27, "911"]

map和collect用法是相同的,主要是很多其他語言當中同樣的處理方法都叫做collect,因此Ruby也提供了相同的語法給不同習慣的開發者使用。

把 Block 物件化

Block 本身並不是物件,它沒辦法單獨的存在 Ruby 的世界裡,需要依附在方法或物件後面。
但其實也是可以把 Block 物件化,例如使用 Proc 類別:

say = Proc.new { puts "哈囉,Ruby" }   # 使用 Proc 類別可把 Block 物件化

要使用它的時候,只要執行這個物件上的 call:

say.call #印出 哈囉 Ruby

如果要帶參數也可以:

say = Proc.new { |name| puts "你好,#{name}"}
say.call("Ruby")

Proc 呼叫方式

要執行一個 Proc 物件,可以使用 call 方法,但其實還有其它好幾種使用方法,例如:

say.call("尼特羅會長")    # 使用 call 方法
say.("尼特羅會長")        # 使用小括號(注意,有多一個小數點)
say["尼特羅會長"]         # 使用中括號
say === "尼特羅會長"      # 使用三個等號
say.yield "尼特羅會長"    # 使用 yield 方法

上一篇
DAY10 方法(Method)
下一篇
DAY12 類別(Class)
系列文
毫無基礎學習 Ruby on Rails 的 甘苦心得30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言