Ruby中Block和迭代器的使用讲解
我们来简单地描述ruby的一个独特特性。block,一种可以和方法调用相关联的代码块,几乎就像参数一样。这是一个不可思议的功能强大的特性。
可以用block实现回调(但它比java的匿名内部(anonymous inner)类更简单),传递一组代码(但它远比c的函数指针灵活),以及实现迭代器。
block只是在花括号或者do...end之间的一组代码。
{puts "hello"} #this is a block do ### club.enroll(person) #and so is this person.socialize # end ###
为什么有两种分界符?部分原因是有人觉得有时候用一种分界符比另外一种感觉更自然。另外一部分原因是它们有不同的优先级:花括号比do/end绑定的更紧密些。我们尝试遵循正在成为ruby标准的一个约定俗成,单行block用花括号,多行block用do/end。
一旦创建了block,就可以与方法的调用相关联。把block的开始放在含有方法调用的源码行的结尾处,就可以实现关联。比如,在下面的代码中,含有puts "hi" 的block与greet方法的调用相关联。
greet {puts "hi"}
如果方法有参数,它们出现在block之前。
verbose_greet("dave","loyal customer"){puts "hi"}
然后使用ruby的yield语句,方法可以一次或多次地调用(invoke)相关联的block。可以把yield想象成比如方法调用,它调用含有yield语句的方法所关联的block。
下面的例子显示了如何使用yield语句。定义了一个方法,它会调用yield两次。然后调用这个方法,把block放在同一行,在方法调用之后(并在方法的所有参数之后)。
def call_block puts "start of method" yield yield puts "end of method" end call_block{puts "in the block"}
输出结果:
strat of method in the block in the block end of method
可以提供参数给yield的调用;参数会传递到block中。在block中,竖线(|)之间给出参数名来接受这些来自yield的参数。
def call_block yield("hello",99) end call_block {|str,num| ...}
在ruby库中大量使用了block来实现迭代器;迭代器是从某种收集(collection)如数组中连续返回元素的方法。
animals = %w(ant bee cat dog elk) #创建一个数组 animals.each{|animal| puts animal} #迭代它的内容
输出结果:
ant bee cat dog elk
让我们看一下如何实现应用在前面例子中的array类中的each迭代器。each迭代器循环处理数组中的元素,对每个元素调用yield。在伪码中,它可能写成:
#在array类中...... def each for each element #<--无效的ruby语句 yield(element) end end
许多内建于c和java等语言的循环结构在ruby中只是方法调用,这些方法会零次或多次地调用相关联的block。
['cat','dog','horse'].each{|name| print name," "} 5.times {print "*"} 3.upto(6){|i| print i} ('a'..'e').each{|char| print char}
输出结果:
cat dog horse *****3456abcde
上面的代码要求对象5 五次调用block;然后要求对象3调用一个block,并传入一个连续的值,直到这个值到达6为止。最后对a到e的字符区间(range),使用each方法调用block。
上一篇: ruby实现github第三方认证
下一篇: Ruby中使用正则表达式的基础指引
推荐阅读
-
Nginx服务器中强制使用缓存的配置及缓存优先级的讲解
-
微信小程序授权 获取用户的openid和session_key【后端使用java语言编写】,我写的是get方式,目的是测试能否获取到微信服务器中的数据,后期我会写上post请求方式。
-
详解Python3中的迭代器和生成器及其区别
-
深入讲解C#编程中嵌套类型和匿名类型的定义与使用
-
Linux中nano和ed文本编辑器的简单使用介绍
-
Python中GeoJson和bokeh-1的使用讲解
-
详谈ES6中的迭代器(Iterator)和生成器(Generator)
-
vue.js中ref和$refs的使用及示例讲解
-
简要说明Ruby中的迭代器
-
Ruby中的p和puts的使用区别浅析