Chinaunix
标题:
ruby扫盲之block
[打印本页]
作者:
zuerrong
时间:
2010-11-18 14:44
标题:
ruby扫盲之block
ruby的block其实就是匿名函数(或C里的函数指针)。
在ruby里,方法大量使用block作为参数,看起来很酷,写起来也很高效。
例如,对这么一个数组:
x = [3,1,4,2,9,0]
想要找出所有小于3的成员,那么大家通常会想到数组的select方法:
z = x.select {|s| s <3}
select方法接受一个block为参数。
那么select具体是如何执行这个block的呢?其实秘密就在于ruby的yield这个方法,它用来执行block。
例如,咱们自己可以写一个myfind方法来代替select:
class Array
def myfind
if block_given?
z = []
each {|s| z << s if yield s}
z
else
raise "no block given"
end
end
end
复制代码
我们首先打开Array类(记住ruby的所有类都是开放的),然后定义myfind函数(def myfind)。
如果有block参数传给myfind,那么执行each {|s| z << s if yield s}这句,表示遍历self数组,把每一个元素作为参数传给yield。
然后yield就执行用户传入的block,并判断执行结果。如果为真就把元素压入z数组,最后返回z数组。
如果没有block传给myfind方法,会raise一个运行时错误,说明"no block given"。
OK 让我们看完整脚本:
x = [3,1,4,2,9,0]
class Array
def myfind
if block_given?
z = []
each {|s| z << s if yield s}
z
else
raise "no block given"
end
end
end
z = x.myfind {|s| s < 3}
p z
复制代码
运行结果为:
$ ruby block.rb
[1, 2, 0]
作者:
2gua
时间:
2010-11-27 11:28
这一系列的Ruby帖的出处在哪儿呀?
作者:
zuerrong
时间:
2010-11-29 09:22
这一系列的Ruby帖的出处在哪儿呀?
2gua 发表于 2010-11-27 11:28
我自己写的哦。。
作者:
ziyiu123
时间:
2011-02-22 18:54
几个问题:
1.block_given? 这个是从哪里来的? 我怎么ri不到?
2.each {|s| z << s if yield s} 中的each,是不是就是self.each,我试了一下结果一样,但是不敢确定,还请lz赐教。
3.楼主男女?
作者:
gr33n
时间:
2011-11-17 02:59
感觉不错,看起来很酷。
作者:
塞图宝
时间:
2014-03-25 07:25
回复
4#
ziyiu123
同问这个
作者:
rubyish
时间:
2014-03-26 03:47
本帖最后由 rubyish 于 2014-04-03 01:36 编辑
作者:
rubyish
时间:
2014-03-26 03:53
本帖最后由 rubyish 于 2014-04-03 01:37 编辑
太感谢了。
作者:
塞图宝
时间:
2014-03-26 06:44
回复
8#
rubyish
:wink: {:3_189:}
作者:
dorodaloo
时间:
2015-12-29 11:48
个人感觉不错之扫盲
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2