1
class SongList
2
def [](key)
3
return @songs[key] if key.kind_of?(Integer)
4
return @songs.find { |aSong| aSong.name == key }
5
end
6
end

2

3

4

5

6

在第四行中,有find这样一个方法,可以按照指定条件对songs进行遍历,最终返回一个符合条件的个体。
下面就来看看这个方法到底是怎么实现的,
1
class Array
2
def find
3
for i in 0
size
4
value = self[i]
5
return value if yield(value)
6
end
7
return nil
8
end
9
end
10
发现是在Array这个类中,增加了一个method,在method中嵌入了一个遍历操作。
2

3


4

5

6

7

8

9

10

如果只是这样的话,那么ruby和其他语言也就没有什么差别了,我们注意到第5行中有yield
这么一个东东。其实他起到了一个代理的作用,实现了实际操作部分和遍历的分离。
再看看下面这个例子,来了解一下yield的功能。
1
def threeTimes
2
yield
3
yield
4
yield
5
end
6
threeTimes { puts "Hello" }
7
8

2

3

4

5

6

7

8

这里定义了名叫threeTimes的blocks, blocks中会重复3次外部的操作,当row 6的代码执行后,会得到后面的结果:





可以看到blocks为我们提供了如此灵活的手段,其实他语言中需要通过代理或接口或函数指针来实现。
其实.net 3.x以后的版本也提供了类似的功能,一个叫LINQ(Language Integrated Query )的东东。
可以使用类似SQL的方式过滤集合













上面的用法是不是很简洁方便?
用ruby来实现的话,将会是这样:
1
names = [ "Geoff", "Jessica", "Mike", "Megan", "Priscilla",
2
"Jack", "Alma" ]
3
4
expr = names.select {
5
|n| n.length == 5
6
}.sort.collect { |n| n.upcase }
7
8
expr.each {|n| puts n }

2

3

4

5

6

7

8

正因为blocks如此方便,在阅读ruby程序的时候,可以看到被广泛的使用着。