为什么6.times.map在ruby 1.8.7中工作,而不是1.8.6

以下代码片段在Mac OS X上的1.8.7中工作正常,但在Ubuntu上的1.8.6中没有。 为什么? 有解决方法吗?

适用于1.8.7:

$ ruby --version ruby 1.8.7 (2009-06-08 patchlevel 173) [universal-darwin10.0] ltredgate15:eegl leem$ irb >> 6.times.map {'foo'} => ["foo", "foo", "foo", "foo", "foo", "foo"] >> 

但不是1.8.6:

 # ruby --version ruby 1.8.6 (2008-08-11 patchlevel 287) [i686-linux] Ruby Enterprise Edition 20090610 # irb irb(main):001:0> 6.times.map {'foo'} LocalJumpError: no block given from (irb):1:in `times' from (irb):1 irb(main):002:0> 

为什么会有区别? 1.8.6的解决方法是什么?

在1.8.7+等迭代器方法中,如果在没有块的情况下调用枚举器,则返回枚举器。 在1.8.6你必须这样做

 require 'enumerator' 6.enum_for(:times).map {...} 

或者对于这个特定的用例,你可以简单地做(0...6).map {...}

在Ruby 1.9中,库已更改,因此如果在没有块的情况下调用它们,迭代将返回Enumerator对象的函数。 许多其他语言function也发生了变化,众所周知,为了改善整个语言,Ruby 1.8.x和Ruby 1.9之间的兼容性会被打破。 大多数人都没有发现这太令人痛苦。

Ruby开发团队认为Ruby 1.8.7应该是一个过渡版本,它添加了Ruby 1.9引入的一些库特性。 他们对这个决定提出了很多批评,许多企业Ruby用户仍然(并且仍有许多人)在Ruby 1.8.6上运行Rails,因为他们觉得1.8.7引入的更改太大了,风险太大。 但是,1.8.7仍然存在,并且具有迭代函数返回枚举器是所包含的function之一。

您在1.8.7中看到的是此迁移function,1.8.6中不存在此function。

sepp2k的答案提供了一个很好的解决方法。 对我来说,添加这个数字并不多。

因为1.8.6 #times在给定块上产生,而1.8.7返回一个Enumerator对象,你可以保持并实现Enumerable。

Ruby 1.8.7引入了许多变化 。 如果你想在Ruby 1.8.6中使用它们,那就简单了

 require 'backports' 

而已。 这给你很多方法1.9.1和即将推出的1.9.2,虽然只需1.8.7的变化就可以require 'backports/1.8.7' ,或者甚至只需要你需要的后端,例如require 'backports/1.8.7/integer/times'