Yield 在 Ruby 跟 Rails 中
喜歡作者的文章嗎?馬上按「關注」,當作者發佈新文章時,思書™就會 email 通知您。
思書是公開的寫作平台,創新的多筆名寫作方式,能用不同的筆名探索不同的寫作內容,無限寫作創意,如果您喜歡寫作分享,一定要來試試! 《 加入思書》
思書™是自由寫作平台,本文為作者之個人意見。
給本文個喜歡
或不
關於作者
很久以前就是個「寫程式的」,其實,什麼程式都不熟⋯⋯
就,這會一點點,那會一點點⋯⋯
看看作者的其他文章
看看思書的其他文章
我是個寫 C 出身的工程師,現在開始學寫 Ruby & Rails,雖然 C 寫的很普普,但是還是有影響, ruby 中總是有些東西,對我來說,很難懂,ruby 的 yield 就是一個例子。
Ruby 的 Yield
Yield 在 Ruby 中是個 keyword,我花了至少一個小時,才總算搞清楚 yield 的來源以及其含義,我個人是這樣,如果不能理解,就是不懂,就算能用,也不過就是隻猴子學樣吧了,自己都難過,所以,特別把它記錄下來,不然很快就又忘了。
在英文中,Yield 這字是:「收成」、「獲得」⋯⋯ ,作為動詞,大家最熟悉的應該就是「讓路」,在美國,就是這個路標:
在台灣也有個相似的:
是的,在 Ruby 中,yield 就是「讓路」,但是要讓給誰能?讓我們來看這個 code:
這個例子很有趣的清楚說明了 yield,我們先來看看這碼的流程:
就這麼簡單,但是,請注意,在 #3 中,執行 autumn_month 方法的時候,後面跟了一個 ruby block
{|mth| "#{mth}. " }
,這個是重點,這個 ruby block 也就是當碰到 yield 讓路時,會先執行(先行)的 ruby block! 還是不懂,沒關係,我也搞好久才懂,模擬一下就懂了:autumn_month()
方法,帶入參數 ( autumn, 9 ),後面跟著{|mth| "#{mth}. " }
這個 ruby block。autumn_month()
方法中,counter
被設定為 9,然後準備印出(puts
) autumn array 的內容puts
)時,裡面有個yield
,因為碰到「讓路」,所以這段碼要先暫停,讓路給{|mth| "#{mth}. " }
,這個已經在等的 ruby block。yield counter
=>yield(counter)
=> 傳出 counter 的值到等待中的 ruby block =>所以 mth = counter
=> ruby block 的內容變成{|counter| "#{counter}. " }
=>"#{counter}. "
,puts "#{yield counter} #{item}"
,這時yield counter
已經變成"#{counter}. "
了,所以puts "#{yield counter} #{item}"
=>puts "#{counter}. #{item}"
,就這樣,魔術完成了!從上面這個很有趣的例子中,我們可以看到,yield 是個很有趣的指令,它可以在呼叫方法時,將一段「程式碼」置入,所以,yield 一定要有相對應的 ruby block,如果我們在寫 yield 時,不確定有沒有相對應的 ruby block,就可以用
yield(value) if block_given?
。在 ruby 中,類似 block 的還有 lambdas 跟 proc,三者之間有很大的相似,但是細節卻大不同,這也是 ruby 對我來說,另一個很難搞懂的地方,有時,從一個老 C programmer 來看,還會覺得超怪,說真的,我是有些排斥用 lambdas 跟 proc,心想,就不用它們,只用block 就可以打天下了,好像是有可能呢,不過,排斥總不是好事,大該寫了一些:
Procs and Lambdas — Today I was refreshing my knowledge and learning something new about proc and lambda in Ruby and want...
DEV Community
Rails 的 Yield
在 Rails 的 layout 中,也有 yield,主要是在 app/views/layouts/application.html.erb 中,在這個 layout 中,就有一個
<%= yield %>
。那,Ruby 跟 Rails 中的這兩個 yield 是相同的嗎?是的,Rails 就是 Ruby 寫的,而 yield 是 Ruby 的 keyword,所以當然就是同一個, 只是在 Rails 中,是由 Controller 來在處理 View 時,它會先取用 Layout(預設是 app/views/layouts/application.html.erb),當碰到
<%= yield %>
時、會將 Controller 相對應的 view 塞到其中,例如:index.html.erb,就這樣。希望有幫助。