首先,我們先為Array新增一個迭代方法iterate!,如下:
class Array
def iterate!
self.each_with_index do |m,i|
self[i] = yield(m)*10
end
end
end
array = [1,2,3,4]
那么我們看看應(yīng)該怎么調(diào)用?
array.iterate! do |m|
m **=2
end
p array #=> [10,40,90,160]
與屬性不同,在方法中不需要指定block的名字,而是使用yield來調(diào)用。yield會執(zhí)行block中的代碼。同時,注意我們是怎么把n(each_with_index當(dāng)前處理的數(shù)字)傳給yield的。傳給yield的參數(shù)即對應(yīng)了block中的參數(shù)(||中的部分)?,F(xiàn)在m就能被block調(diào)用并在yield調(diào)用中返回m**2。
整個調(diào)用如下:
- 一個整數(shù)組成的數(shù)組調(diào)用iterate!
- 當(dāng)yield被調(diào)用時,把m(第一次為1,第二次為2,…)傳給block
- block對m進(jìn)行m**2。因?yàn)槭亲詈笠恍校詣幼鳛榻Y(jié)果返回。
- yield得到block的結(jié)果,并把值*10后重寫到array里。
- 數(shù)據(jù)中每個對象執(zhí)行相同操作。
那么這樣寫的輸出是什么呢?
array.iterate! do |m|
m **=2
m+2
end
p array #=> [30,60,110,180]
即把block中的m+2的值傳給了yield,此時的m已經(jīng)做過平方的計(jì)算了。然后再*10后重寫到array里。
那么這樣寫的輸入又如何呢?
array.iterate! do |m|
m **=2
m+2
n = 100000
end
p array #=> [1000000,1000000,1000000,1000000]
即把block中的n的值傳給了yield。
繼續(xù)往下嘗試
k = 0
array.iterate! do |m|
m **=2
m+2
n = 100000
k
end
p array #=> [0,0,0,0]
即把block中的k的值傳給了yield。
由此可知,ruby會把block中最后一個表達(dá)式的值傳給迭代方法中的yield,然后再進(jìn)行計(jì)算。
甚至可以這樣:
class Array
def iterate!
self.each_with_index do |m,i|
$a ||= []
$a << yield(m)*10
end
end
end
$a
array = [1,2,3,4]
k = 0.9
array.iterate! do |m|
m **=2
end
p $a #=> [10, 40, 90, 160]