Day19 描述Ruby裡的yield用法? What is yield statement in Ruby?
yield + block在第11天時,我們曾比較block, proc與lamdba方法,而yield的使用場景是在method裡讓路給block區塊執行程式的意思。
現在來寫一個IronmanDairy類別,用以產生新物件day19,接著利用get_topic方法透過yield傳遞參數topic給block:
class IronmanDairy
  def initialize(topic)
       @topic = topic
  end
  def get_topic
      yield(@topic)
  end
end
day19 = IronmanDairy.new("Yield")
#invoking the method passing a block
day19.get_topic do |topic|
    puts "We are going to talk about #{topic} today!"
end
從第12天文章比較實體變數與類別實體變數的整理,我們可以了解這裡的@topic是實體變數。
Output:
tingdeMacBook-Air:Ironman tingtinghsu$ ruby yield.rb
We are going to talk about Yield today!
今天的Opening出現啦!
yield + block: 字串方法Block裡面還可以玩許多有趣的String字串方法。例如,我們想要把大寫字母轉小寫、小寫字母轉大寫:
topic_swapcase = "" #set an empty string
day19.get_topic do |topic|
  topic_swapcase = topic.swapcase
end
puts "We are going to talk about #{topic_swapcase} today!"
Output:
tingdeMacBook-Air:Ironman tingtinghsu$ ruby yield_swapcase.rb
We are going to talk about yIELD today!
yield + block: 陣列方法在寫鐵人賽的我目前所在城市是Sydney,南半球的現在正是花朵盛開、氣候美妙的春天~我想用array表達曼妙愉快的心情:
spring = ["September",
  "October",
  "November"]
我想要將春天的三個月份條列印出在螢幕上,可以寫成print_list方法:
spring = ["September",
  "October",
  "November"]
def spring_month (array, start = 1)
  counter = start
  array.each do |item|
    puts "#{counter} #{item}"
    counter=counter.next
  end
end
spring_month( spring ) { |mth| mth }
當我們呼叫spring_month方法時,可傳入試先設定好的spring陣列,再用block方式跑完每一個陣列裡的值。(記得{}和do...end都是block的語法唷!)
Output:
1 September
2 October
3 November
現在,我想月份前面加上對應的阿拉伯數字,例如September是9,October是10...。該如何是好呢?
這時候yield就派上用場啦!
我們把yield放在計數器counter前,當作設定格式的一種方式:
puts "#{yield counter} #{item}"
yield會去呼叫以下的block:
spring_month( spring, 9 ) do |mth|
  "#{mth}. "
end
為了要讓第一個item是September從9開始,呼叫spring_month方法時,也要代入參數9,讓spring_month方法幫助我們從9開始往上遞增。並且利用"#{mth}. "設定格式。
整體結構如下:
spring = ["September",
  "October",
  "November"]
def spring_month (array, start)
  counter = start
  array.each do |item|
    puts "#{yield counter} #{item}"
    counter=counter.next
  end
end
#list all the months in Spring
spring_month( spring, 9 ) do |mth|
  "#{mth}. "
end
output:
9.  September
10.  October
11.  November
以上的例子顯示,方法裡面可以結合陣列,在block裡面透過array#eachmethod對陣列裡的元素做出各種有趣的功能,再結合yield之後,是不是產生很大的威力呢?:)
Ref: