Ruby中Block和迭代器的使用讲解_ruby专题

我们来简单地描述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
block
ruby迭代器、迭代器的使用、java中迭代器的使用、迭代器使用、为什么要使用迭代器,以便于您获取更多的相关知识。

时间: 2024-10-22 10:20:10

Ruby中Block和迭代器的使用讲解_ruby专题的相关文章

Ruby中的循环语句的用法教程_ruby专题

 Ruby中的循环用于执行相同的代码块指定的次数.本章将详细介绍Ruby支持的循环语句.Ruby while 语句:语法: while conditional [do]    code end 执行代码当条件为true时.while循环的条件是代码中的保留字,换行,反斜杠(\)或一个分号隔开. 实例: #!/usr/bin/ruby $i = 0 $num = 5 while $i < $num do puts("Inside the loop i = #$i" ) $i +=1

Ruby中操作字符串的一些基本方法_ruby专题

 在Ruby中的String对象持有和操纵的任意序列的一个或多个字节,通常表示人类语言的字符表示. 简单的字符串文本括在单引号(单引号字符).引号内的文本的字符串值: 'This is a simple Ruby string literal' 如果需要内放置一个单引号,单引号的字符串文字,在它前面加上一个反斜杠Ruby解释器不认为终止字符串: 'Won\'t you read O\'Reilly\'s book?' 反斜杠也可以转义另一个反斜杠,这样第二个反斜杠本身不是解释为转义字符. 以下是

Ruby中使用连续体Continuation实现生成器_ruby专题

ruby中有很多经典的驱动器结构,比如枚举器和生成器等.这次简单介绍下生成器的概念.生成器是按照功能要求,一次产生一个对象,或称之为生成一个对象的方法.ruby中的连续体正好可以用来完成生成器的功能.连续体说起来晦涩,其实还是很简单的,它有3个特点: 1. callcc方法会给代码块传一个连续体对象,你可以保存该对象; 2. 当调用连续体的call方法时指令流会跳转到callcc方法之后; 3. 如果给连续体的call方法传递对象,则callcc方法会返回该对象,如果不传递对象,callcc会返

Ruby中Time对象的常用函数总结_ruby专题

时间对象. Time.now返回当前时间. 1.Time.at Time.at(time[, usec]) 返回time所指时间的Time对象. time可以是Time对象,也可以是表示自起算时间以来的秒数的整数或浮点数. 若浮点精度不够时,可以使用usec. 它将返回time +(usec/1000000)所表示的时间. 此时,time和usec都必需是整数. 生成的Time对象将使用地方时的时区. 2.Time.gm.Time.utc Time.gm(year[, mon[, day[, h

Ruby中关于模块的一些基础知识_ruby专题

模块与类很相似,它也可以说成是"不能被实例化的类".由于Class类是Module类的子类,所以说成是"类=模块+实例化能力"也许更好. 所谓模块,究竟是用来干什么的呢?其作用主要有两大类:Mix-in和命名空间. Mix-in实际上是受限制的多重继承.利用实际做成的继承关系,可以实现对某些类进行一些"点缀"的目的.事实上,Mix-in这种说法就来自于在冰激凌上面的饼干或者坚果. 在面向对象设计的历史中,由多重继承机制造成的问题早已众所周知了.所

详解Ruby中的单件方法和单件类_ruby专题

单件方法 Ruby允许给单个对象增加方法,这种只针对单个对象生效的方法,称为单件方法 示例代码 str = "just a regular string" def str.title? self.upcase == self end str.title? # => false str.methods.grep(/title?/) # => [:title?] str.singleton_methods #=> [:title?] str.class # => S

在Ruby中处理日期和时间的教程_ruby专题

Time 类在 Ruby 中用于表示日期和时间.它是基于操作系统提供的系统日期和时间之上.该类可能无法表示 1970 年之前或者 2038 年之后的日期. 本教程将让您熟悉日期和时间的所有重要的概念.创建当前的日期和时间 下面是获取当前的日期和时间的简单实例: #!/usr/bin/ruby -w time1 = Time.new puts "Current Time : " + time1.inspect # Time.now 是一个同义词 time2 = Time.now puts

Ruby中检测Gem是否安装的方法_ruby专题

最近参加七牛的demo大赛,决定使用ruby开发.于是遇到了一些疑问,然后解决了,这里记录一下. 在Ruby中,Gem是一个很常见的东西,其相当于插件,Ruby有很多很棒的gem,避免了我们重复造轮子,我的demo中需要安装gem,但是为了更加实现好一些,先检测gem是否已经安装,如果没有安装,在继续安装,否则不安装. 于是,怎么在Ruby中检测gem是否安装呢,其实也很简单,直接上代码就可以了.不需太多解释.begin-rescue-相当于java中的try catch. 复制代码 代码如下:

浅析Ruby中继承和消息的相关知识_ruby专题

继承允许你创建一个类,作为另一个类的精炼(refinement)和特化(specialization).例如,在我们的自动点唱机系统中,有"歌曲"这一概念,被封装在Song类中,然后,随着市场的成长,我们需要提供卡拉OK的支持.一首卡拉OK歌曲和其他歌曲没什么两样(它只是没有主唱的音轨,对此我们不必关心).不过,它还包括对于的一套歌词以及时间信息.当我们的自动点唱机在播放一首卡拉OK歌曲时,歌词应该随音乐滚动显示在点唱机前的屏幕上. 解决这个问题的一种方法是定义一个新的类Karaoke