1 | loop {puts "loop forever" } |
loop是一个迭代器,是一种方法。他在调用的语法上附加了一个条件:需要额外提供一个代码块。
loop方法访问了在代码块中的代码:方法可以调用执行该代码块。为了在迭代器中实现它,可以使用关键字yield。代码块(由调用代码提供)和yield(从方法内部调用)一同作为调用的主要条件。
迭代
loop的任务是为了把控制教改代码块,然后不断的循环。
1 | def my_loop |
然后就可以像调用loop一样使用my_loop
提供一个代码块给my_loop方法,就能交出控制权(yield)。当方法的控制权交给代码块,其中的代码运行完毕之后,控制权会立刻返回到方法中调用yield的的地方。
解析方法调用
Ruby中的每个方法调用都遵循一下的语法:
- 接收者对象或者变量(如果缺少则默认为self
- 点(假如有明确的接收者则为必要条件,不允许其他情况
- 方法名(必要
- 参数列表(可选,默认为
() - 代码块(可选,没有默认
要注意的是,参数列表和代码块是分离的,他们是独立变化的个体,如下有部分实例
1 | loop { puts "Hi"} |
方法调用有没有代码块的区别在于方法内部是否有yield子句可以调用。如果有代码块,则可以调用,如果没有则不能。
假如将代码块作为方法调用的语法元素而不是作为参数来考虑,那么就能够对以迭代为基础的更多变化有更清晰的思路。
Times方法
times方法是一个Integer类的实例方法,这意味着可以在整型对象上调用它,根据整型的数值n来运行n次代码,并在方法的结尾返回数值n。
1 | 5.times { i puts "this is the #{i} times"} |

times的行为说明了一个很美好的事实:使用yield运行一个代码块和从方法返回值是截然不同的事情。一个方法可以从0到无限多次调用他的yield语句。但是每次方法完成所有事情后,他将会严格的返回一次(确保没有错误的情况下)。
从each方法到map方法
each方法很简单:在集合对象上运行each方法,他把集合中的元素逐个的去除传递给代码块。Ruby中有很多集合类,甚至像一些很像集合的类都支持each方法。
1 | array = [1,2,3,4,5] |

同时,each方法没有返回值,但是他会因为自身将取出的值传递给block,每取一次就会产生一个值。
和each方法类似的是map方法,map方法一次遍历数组的一个元素,然后传递给代码块。
不同的地方在于,each方法返回它的接收者,map方法返回一个新数组。新数组的大小和原来的一致,但是元素和原始元素不同,新数组包含的元素由迭代代码块的返回值构成:
1 | array = [1,2,3,4,5] |

新数组的映射结果中,其每一个元素都对应在原始数组的相同位置,只是经过了代码的处理。
在迭代分析过程中使用map是考虑到代码会返回一个值给调用它的方法,虽然仅只有方法可以调用yield并传递一个值,但是代码块能返回一个值,这个返回值作为调用yield的值返回。
- Post title:Ruby-迭代器和代码块
- Post author:Varsion
- Create time:2020-09-07 15:15:53
- Post link:https://blog.varsion.cn/post/1a6aef8c.html
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.