Ruby代碼塊實現傳遞代碼
Ruby語言中有許多和其他語言不通的特性,值得我們在學習和實踐中去深入的探討。比如今天我們為大家介紹的Ruby代碼塊,就是一個功能強大的一系列代碼應用。#t#
Ruby代碼塊可以和方法調用關聯的一系列代碼,就好像這些代碼是方法的參數一樣,這是一個令人難以置信的強大特性。你可以使用代碼塊實現回調(但不像Java的匿名內部類那么簡單),傳遞一系列代碼(但要比C的函數指針更加復雜),和實現迭代器。
Ruby代碼塊是用大括號或者do...end括起來的一系列代碼。
- { puts "Hello" }
# 這是一個代碼塊 - do #
- club.enroll(person)
- # 這也是代碼塊
- person.socialize #
- end
一旦你創建了一個代碼塊,就可以把它和一個方法調用關聯在一起。那個方法能夠調用代碼塊一次或者更多次,用Ruby的yield語句。下面的例子顯示了這個過程。我們定義一個方法,這個方法調用yield兩次。然后我們調用這個方法,把代碼塊放在同一行中方法調用的后面(也是方法的所有參數的后面)。[有些人喜歡把和方法關聯的Ruby代碼塊當作是一種傳遞過來的參數。它們雖然是一個級別的,但這沒有顯示出所有的內涵。***把代碼塊和方法當成是協同工作的關系,在它們之間控制在來回交換。
- def callBlock
- yield
- yield
- end
- callBlock { puts "In the block" }
結果:
In the block
In the block
看看Ruby代碼塊中的代碼(puts "In the block") 是如何被執行兩次的,就是對yield的每一次調用。
你可以在調用yield時給出參數,這些參數傳遞給代碼塊。在代碼塊中,列舉變量的名字來接受參數,這些參數被用"|"括著。
- def callBlock
- yield ,
- end
- callBlock { |, | ... }
Ruby代碼塊貫穿在實現迭代器的Ruby庫中,迭代器就是一種方法,用來連續返回某種集合的元素,比如一個數組。
- a = %w( ant bee cat dog elk )
# 創建一個數組- a.each { |animal| puts animal }
# 迭代所有的內容- produces:
- ant
- bee
- cat
- dog
- elk
我們來看看實現Array類的each迭代器的可能的方法,我們要用到前面的例子。each迭代器遍歷數組的每個元素,每次都調用yield,類似的代碼可能會是下面這樣:
- # 在Array類中...
- def each
- for each element
- yield(element)
- end
- end
這樣你就可以使用數組的each方法來迭代數組元素提供給代碼塊,Ruby代碼塊依次在每個元素返回時被調用一次。
- [ 'cat', 'dog', 'horse' ]
.each do |animal|- print animal, " -- "
- end
結果:
cat -- dog -- horse --
類似的,內置在語言比如C或者Java中的許多循環結構在Ruby中就是簡單的方法調用,這個方法調用所關聯的代碼塊0次或者更多次。
- 5.times { print "*" }
- 3.upto(6) {|i| print i }
//puts是每打印一個就有回車的,print沒有- ('a'..'e').each {|char| print char }
結果:
*****3456abcde
在這里,我們讓數字5調用一個代碼塊5次,然后讓數字3調用一個Ruby代碼塊,傳遞給它連續的數值直到6,***,字符"a"到"e"的區間使用each方法調用一個塊。