为什么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'