塊和閉包(block and Closures)

來源:互聯網
上載者:User
http://www.ruby-cn.org/可以參見http://martinfowler.com/bliki/Closures.html

        塊(block):只是一段代碼,相當於一個匿名函數;閉包(Closures):一段代碼,能作為參數傳遞給其它方法。
讓我們再回來看看自動點唱機,某些時候,我們需要處理點唱機和使用者的介面:很多按鈕,供使用者選擇歌曲和控制播放,我們需要給這些按鈕指定相應的時間處理代碼,而Ruby中的block就很適合幹這樣的事情。假設點唱機的設計者通過Ruby擴充為我們提供了一個基本的按鈕類。

bStart = Button.new("Start")bPause = Button.new("Pause")# ...

當使用者按下按鈕之後如何處理呢?Button類提供了一個buttonPressed方法,在按鈕按下時能被回調。所以最簡單的方法建立Button的子類,然後在每個子類中實現buttonPressed 方法。

class StartButton < Button  def initialize    super("Start")       # invoke Button's initialize  end  def buttonPressed    # do start actions...  endend

bStart = StartButton.new

這樣做有兩個問題,首先這樣將產生大量子類,如果Button變化了,所有子類都需要維護;第二,按鈕按下之後需要執行的行為不應該在按鈕上表示,這是點唱機的責任。我們可以用塊來消除這些問題

class JukeboxButton < Button  def initialize(label, &action)    super(label)    @action = action  end  def buttonPressed    @action.call(self)  endend bStart = JukeboxButton.new("Start") { songList.start }   bPause = JukeboxButton.new("Pause") { songList.pause } 

上面代碼的關鍵點在JukeboxButton#initialize的第二個參數,這個參數前面帶有一個&符號,在Ruby中代表這個參數是一個塊,這個塊將會被轉化為一個Proc對象,並關聯道相應變數。在本例中我們把它賦給執行個體變數@action 。當回調方法buttonPressed 執行時,我們用方法Proc#call來調用相應的block。

當建立一個Proc對象之後我們得到的是什麼呢?很有趣,我們得到的不僅是一串代碼。和這個block定義相關聯的上下文環境(範圍內的):self值,定義它的方法,變數,常量等。Ruby中的一個有趣的地方就是即使block定義時候的變數已經不在它的使用範圍內,這個變數還保留著,仍可以使用

我們來看一個例子,這個例子用了方法proc,這個方法把一個block變為了一個Proc對象。

def nTimes(aThing)
  return proc { |n| aThing * n }
end
p1 = nTimes(23)
p1.call(3) » 69
p1.call(4) » 92
p2 = nTimes("Hello ")
p2.call(3) » "Hello Hello Hello "

        方法nTimes 返回一個Proc對象,這個對象引用了這個函數的參數:aThing即使這個參數在塊被調用時已經不在自己的範圍裡了,這個塊還是可以訪問這個參數。(比如p1.call(4),這個時候,雖然對p1的指派陳述式中的參數23已經超出了範圍範圍,但是它仍然儲存著23×4=92。)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.