iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 12
0
Software Development

Ruby 研究 30 天系列 第 12

Day 11 - Block

  • 分享至 

  • xImage
  •  

Block

今天要來介紹 block花括號{}do ... end

  • 不能指定給變數:在 Ruby 中 block 不能單獨存在,也就不能賦值給其他物件。

  • 不能當參數傳進方法:也因為不是物件,沒有所謂的值,因此不能當作參數使用。

(1..5).map {|i| i * 2 if i >= 3}

# 上下兩段程式碼會得到相同的結果

(1..5).map do |i|
  i * 2 if i >= 3
end

怎麼讓 block 活起來呢?從上面的例子可以看到 block 裡通常是一段程式碼,也就是說,只要用對方法,我們就不單單能把參數傳來傳去,甚至可以把一段程式碼帶入。

所以,我們第一件要做的事就是先把 block 物件化,比較常見的有三種方法:

Proc.new

我們可以用 Proc.new{}block 物件化,物件化後就是一個參數,再搭配 call 方法執行 block 內的程式碼:

class Office
  def self_introduction(string, sentence)
    puts string
    puts sentence.call(18)
    # 也可寫成sentence[18]
  end
end

staff = Office.new
my_age = Proc.new {|age| "I'm #{age} years old"}
# 上一行也可以寫成 my_age = proc {|age| "I'm #{age} years old"}
staff.self_introduction("Hello", my_age)

# 印出 Hello
# I'm 18 years old

yield

block 直接掛在方法後面,整段程式碼最會被 yield 的接住,可以想成把 block 的 {} 脱掉直接放進方法中。

class Office
  def self_introduction(string)
    puts string
    puts yield(18)
  end
end

staff = Office.new
staff.self_introduction("Hello"){ |age| "I'm #{age} years old" }

# 印出 Hello
# I'm 18 years old

&

也許可以想成上述方法的綜合體( proc 頭, yield 腳),如同 yield 一樣直接把 block 掛在方法後面,又能夠把 block 當做參數:

class Office
  def self_introduction(string, & sentence)
    puts string
    puts sentence.call(18)
  end
end

staff = Office.new
staff.self_introduction("Hello"){ |age| "I'm #{age} years old" }

# 印出 Hello
# I'm 18 years old

以上是三種常用的 block 物件化方法,個人認為 Proc way 的好處是按步驟把 block 物件化後指定給一個變數,對於新手學習來說很直觀,需要反覆用到那個 block 時也方便;而 yield way 則是可以讓程式碼參數最少、行數最少,更能一眼看出程式碼的用途。
至於解決方法沒有好不好,只有適不適合,下一篇我們拿一個事件觸發的題目用 & 演練看看。

此文同步刊登於CJ-Han的網站


上一篇
Day 10 - Ruby 裡的非物件
下一篇
Day 12 - 事件觸發 ( EventEmitter )
系列文
Ruby 研究 30 天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言