由于版本的变更,1.8与1.9在许多地方是不一样的,API变化很大,虽然理论上说1.9要好,但是目前有很多应用还是基于1.8的,在windows玩ruby更是如此,因此必须得注意这两个版本间的一些区别,比如说Enumerator,首先Enumerator是一个类,代码如:
class Enumerator
include Enumerable
.....
从上面这段代码可以看出,一个Enumerator对象就是一个Enumerable对象。但Enumerator与Enumerable目的是不同的,Enumerator目的在于枚举其它的对象。主要作用有两个:
一、作为Enumerable的代理对象。如to_enum等,返回一个不可变的代理Enumerator。
创建一个Enumerator对象也很简单,一般使用Object的to_enum或enum_for方法。to_enum返回一个可枚举但不可变的代理对象。
遍历数据加上索引时,
在1.8中
require 'enumerator'
foo.to_enum(:each_with_index).collect {|x,i| }
其中each_with_index是一个迭代器方法,即基于each_with_index的方式来迭代。
也可以这样:
require 'enumerator'
[1,2,3].enum_with_index.map{|x, i| }
在本人机子上装的是1.8.7,此版本已经内置了enumerator,所以不用require 'enumerator'也是可以运行的,包括each_slice也是。
在1.9中:
#map也可以
foo.collect.with_index {|x,i| }
两个版本的用法之所以不同,是因为在1.8中,collect或map返回的是一个Array对象,而在1.9中,返回的是却是Enumerator对象,只有Enumerator才有with_index方法,可能在1.8.7前的版本没有with_index,但是在1.8.7中是有with_index方法的。下面代码在1.8.7与1.9.1中都是可以运行的。
s="hi, how are you!"
s.each_char.with_index{ |args,arg| }
二、作为外部迭代器使用。
Enumerator有个next方法,用于返回下一个元素,但是没有next?之类的方法,所以需要通过StopIterator异常来判断。而在1.9中(其实187也是可以的),Kernel.loop包含了一个隐式的rescue语句,如果此方法内部抛出StopIterator异常,循环将中止。如:
iterator = 9.downto(1);
loop do
print iterator.next
end
关于内部迭代器与外部迭代器:
引用
一个基本的问题是决定到底由哪一方来控制迭代,是迭代器自身还是使用迭代器的客户代码?当客户代码控制迭代时,该迭代器被称为外部迭代器,反之当迭代器控制迭代时,该迭代器就是一个内部迭代器。那些使用外部迭代器的客户代码必须负责推进整个遍历过程并且显式的从迭代器中获得下一个元素。相比之下,在使用内部迭代器时,客户代码将一个操作传递给一个内部迭代器,该迭代器依次在每个元素上应用该操作。
外部迭代器比内部迭代器更灵活。比如,使用外部迭代器可以很容易的比较两个集合的相等性,如果用内部迭代器则不太可能。但是从另一个角度来看,内部迭代器更容易使用,因为它们已经为你定义好了迭代逻辑。
在Ruby中,像each这样的迭代器方法是内部迭代器,它们控制着迭代并且将值“推送”给那个与方法调用相关联的代码块。Enumerator枚举器具有一个each方法,可用于内部迭代,但是在Ruby1.9及其后的版本里,它们还能充当外部迭代器,客户代码可以使用next方法顺序的从一个枚举器中“取出"值。
分享到:
相关推荐
这是 Ruby语言核心建议的替代方法。 目标是相同的:生成枚举器,这些枚举器可以惯用地替换(大部分) while和loop周期。 经过一些实验,结果证明“从初始值开始,然后继续该块”(就像Object#enumerate一样)并不...
@Enumerator::Lazy@, which adds support for lazy access to potentially infinite lists. Refinements allow you to encapsulate changes to third-party classes, and scope their application to individual ...
EnumeratorKit, 在 Objective C 中,ruby 样式枚举 EnumeratorKit - objective-c 中的ruby样式枚举 EnumeratorKit是一个集合枚举库,在 ruby 模块和 Enumerator 类的Enumerable 之后建模。它允许你用一个非常 comp
枚举器::并行 require 'enumerator-parallel'[ 1 , 2 , 3 ] . par ( processes : 3 ) . each { | n | sleep 1 ; p n } 3倍的父亲! 哇哇哇enumerator-parallel保持结果的顺序 (^o^) [ 1 , 2 , 3 ] . par ( threads :...
j-enum 这是我对 Ruby 的Enumerable模块和Enumerator类的实现。 这是加深我对这些工具的理解的练习。 利用 。
它返回一个Enumerator因此您可以调用 Ruby Enumerator类任何方法。 安装 将此行添加到应用程序的 Gemfile 中: gem 'path_generator' 然后执行: $ bundle 或者自己安装: $ gem install path_generator 用法...
我在2015年7月在RUG :: B(柏林Ruby用户小组)中发表的演讲中的示例。 在examples/目录中浏览示例。 您也可以下载并运行它们,它们都可以工作。 滑梯 如果有用的话,这是幻灯片。 GIF Nadine Angerer和Jennifer ...
这是一个很小的方法(恰好是一种方法),向我展示了我对Ruby核心的建议。 。 开发者会议的: 成濑:有趣的建议 Akr:向Object添加方法听起来对我来说太激进了。 美国:我认为这是一种可枚举的方法。 Shyouhei...
IB-Ruby使用相同的概念来组织和优化运营问题,并支持研究和系统的交易工作。 列表按Enumerator进行组织,以扩展其使用范围。 该功能完全存在于文件系统中,不需要数据库,不涉及任何进一步的依赖关系。 默认情况下...
给定一个可枚举的sort_by proc,此gem将把输入数据分解为已排序的块,保留这些块,并返回Enumerator 。 从此枚举器读取的数据将按其最终排序顺序。 块的大小以及用于序列化和反序列化数据的策略是可配置的。 该...
Tabulo是用于生成纯文本表(也称为“终端表”或“ ASCII表”)的Ruby库。 它是高度可配置的,并且非常易于使用。 总览 快速API: > puts Tabulo::Table.new(User.all, :id, :first_name, :last_name).pack +----+-...