讀代碼學RUBY之閉包

來源:互聯網
上載者:User
#代碼來源:http://rubyer.me/blog/917順便學習 Ruby的4種閉包:blocks, Procs, lambdas 和 Methods。
#firstclass Array  def iterate!    self.each_with_index do |n, i|      self[i] = yield(n)      yield(n)    end  endendarray = [1, 2, 3, 4]array.iterate! do |x|  x ** 2endputs array.inspect# => [1, 4, 9, 16]#secondclass Array    def iterate!(&code)  #為iterate!傳遞一個參數&code,&表示這個參數是block。        self.each_with_index do |n,i|            self[i] = code.call(n)  #在iterate!中沒有使用yield而是call。        end    endendarray.iterate! do |n|    n ** 2endputs array.inspect#third# ---PROC Procs 過程block與Proc惟一的不同是:block是不能儲存的Proc,一次性的。square = Proc.new do |n|    n ** 2endclass Array  def iterate!(code) #now these is not &code, not null, but code !!      #注意:並沒有在 iterate!的參數頭部添加&,因為Proc只是一個普通類,不需要特殊處理。    self.each_with_index do |n, i|      self[i] = code.call(n)    end  endendarray.iterate! square puts array.inspect

  

來源:http://rubyer.me/blog/917  

首先,我們開啟Array,並添加進iterate!方法。方法名以!結尾表示危險方法,引起注意。現在我們就可能像使用collect!一樣使用iterate!

與屬性不同,在方法中不需要指定block的名字,而是使用yield來調用。yield會執行block中的代碼。同時,注意我們是怎麼把n(each_with_index當前處理的數字)傳給yield的。傳給yield的參數即對應了block中的參數(||中的部分)。現在n就能被block調用並在yield調用中返回n**2。
整個調用如下:
1、一個整數組成的數組調用iterate!
2、當yield被調用時,把n(第一次為1,第二次為2,…)傳給block
3、block對n進行n**2。因為是最後一行,自動作為結果返回。
4、yield得到block的結果,並把值重寫到array裡(這裡用了self,在class和module的定義中,self代表這個class或這module對象,拓展閱讀:http://fuliang.iteye.com/blog/272370)。
5、資料中每個對象執行相同操作。

 

def callbacks(procs)  procs[:starting].call  puts "Still going"  procs[:finishing].callendcallbacks(:starting => Proc.new { puts "Starting" },          :finishing => Proc.new { puts "Finishing" })# => Starting# => Still going# => Finishing

 1、(:starting => Proc.new { puts "Starting" }, :finishing => Proc.new { puts "Finishing" } ) 這裡定義了一個雜湊表或者說字串符號 (Symbol) 。(一個 Symbol 物件皆為冒號開頭,例如 :foo 或 :foo_bar。它的作用就是代表一個名字,最大的作用就是當做 Hash 的鍵 (key),例如{ :foo => 1, :bar => 2 },在這裡我們只需要一個識別的名字,不需要使用字串物件。使用 Symbol 寫法更簡潔和獲得效能上的好處。)

   2、:starting => Proc.new { puts "Starting" } 鍵KEY為 :starting,鍵VALUE為 一個Procs 過程。

   3、procs[:starting].call 直接調用 儲存在 procs[:starting] 中的 Procs 過程

 BTW:什麼時候用blocks而不用Procs呢?我一般這樣判斷:
1、Block:方法把一個對象拆分成很多片段,並且你希望你的使用者可以與這些片段做一些互動。
2、Block:希望自動運行多個語句,如資料庫遷移(database migration)。
3、Proc:希望多次複用一段代碼。
4、Proc:方法有一個或多個回調方法(callbacks)。


未完,明天繼續。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.