Code blocks是Ruby特有的很強(qiáng)大的特點(diǎn)甲锡。
可以通過(guò)這個(gè)實(shí)現(xiàn)回調(diào)兆蕉。
對(duì)比###
- Java的匿名內(nèi)部類(lèi)更加簡(jiǎn)單。
- 比C語(yǔ)言的指針簡(jiǎn)單缤沦。
兩種寫(xiě)作形式###
{puts "hello"}
以及:
do
club.enroll(person)
person.socialize
end
比較好的規(guī)范是:?jiǎn)涡杏玫谝环N虎韵,多行代碼用第二種。
使用方式###
在函數(shù)調(diào)用后面寫(xiě):
greet {puts "Hi"}
其中g(shù)reet是函數(shù)名缸废,如果該函數(shù)有參數(shù)包蓝,那么參數(shù)要出現(xiàn)在代碼塊(code block)前面。
Ruby中函數(shù)沒(méi)有參數(shù)企量,可以省略括號(hào)测萎。
如:
greet("Dave","loyal customer") {puts "Hi"}
這種形式好像就是函數(shù)定義了,但注意這里是在Ruby届巩,函數(shù)定義不同于C語(yǔ)言或者Java語(yǔ)言硅瞧。
上面只是說(shuō)明code blocks放置的位置,其實(shí)并沒(méi)有調(diào)用塊中的內(nèi)容恕汇。
調(diào)用code blocks###
學(xué)習(xí)一個(gè)關(guān)鍵字:yield
def call_back
puts "Start of method"
yield
yield
puts "End of method"
end
call_block { puts "In the block"}
這樣一調(diào)用函數(shù)腕唧,在內(nèi)部有兩個(gè)聲音在喊,調(diào)用后面的code block!因?yàn)楣灿袃蓚€(gè)聲音(yield)瘾英,所以調(diào)用兩次枣接。
輸出結(jié)果是:
Start of method
In the block
In the block
End of method
yield什么###
上面的例子中,yield只是喊缺谴,但是并沒(méi)有喊出獨(dú)特的聲音來(lái)但惶。既然有這樣的發(fā)聲通道,是不是可以定制化地喊出自己的聲音呢湿蛔?
答案是可以的:為yield提供參數(shù)榆骚。
def who_says_what
yield("Dave","hello") #通過(guò)yield喊出自己的聲音
yield("Andy","goodbye")
end
who_says_what {|person,phase| puts "#{person} says #{phase}"}
通過(guò)在yield
中定制參數(shù),參數(shù)值將會(huì)被傳遞到code block中煌集。
但是code block如何接過(guò)來(lái)妓肢,需要一定的格式。
不同于函數(shù)苫纤,code block接參數(shù)的方式是在兩個(gè)豎線內(nèi)碉钠。關(guān)于這點(diǎn)纲缓,有一個(gè)很有趣的說(shuō)明:
有些人認(rèn)為,這種傳遞就像是函數(shù)傳遞參數(shù)喊废。這樣的理解有一定道理祝高,但也并非“全部的故事”。最好將這種方式看作是"coroutine"污筷,運(yùn)行時(shí)控制權(quán)在二者之間來(lái)回轉(zhuǎn)換工闺。
結(jié)合數(shù)組一起服用###
animals = %w{ ant bee cat dog} #構(gòu)造一個(gè)數(shù)組
animals.each {|animal| puts animal} #array.each是個(gè)函數(shù),后面跟的是code block
#輸出:
ant
bee
cat
dog
雖然沒(méi)有看底層源碼瓣蛀,但也可以想到each函數(shù)中有yield
,否則不會(huì)調(diào)用后面的code block陆蟆。
開(kāi)吃一些語(yǔ)法糖##
['cat', 'dog','horse'].each {|name| print name, " "}
5.times { print "*"}
3.upto(6) {|i| print i}
('a'..'e').each {|char| print char}
puts
#輸出
cat dog horse *****3456abcde
注意數(shù)字是對(duì)象,對(duì)象必然自帶了一些函數(shù)