1

我写了一些代码:

output = File.open(text_file).collect.reverse.join("<BR>")

它似乎在 1.8.7 上可以正常工作,但会引发错误

NoMethodError - undefined method 'reverse' for #<Enumerator: #<File:C:\EduTester\cron\rufus.log>:collect>:

在 1.9.1 上(红宝石 1.9.3p194 (2012-04-20) [i386-mingw32])

有人知道为什么会发生这种情况以及如何解决这个问题吗?(为什么我最感兴趣。)

4

4 回答 4

5

首先如何解决它 - 你应该这样做:

output = File.open(text_file).to_a.reverse.join("<BR>") 

这将适用于任一版本的 Ruby。基本上,您需要将文件转换为行数组(使用.to_a),然后再反转它们并添加换行符。

就原因而言(这有点技术性):File混合在Enumerable模块中,这给它提供了类似collect. 现在在 Ruby 1.87 中,如果你在Enumberable.collect没有块的情况下调用它会返回一个Array. 但是在 1.9 中,它返回一个Enumerator- 不响应该reverse方法。

以下是相关方法的 2 个版本:

http://ruby-doc.org/core-1.8.7/Enumerable.html#method-i-collect
http://ruby-doc.org/core-1.9.3/Enumerable.html#method-i-collect

所以基本上在 1.9 之前.collect是一个(hacky)等价于.to_a. 但总是.to_a用来把东西变成数组。

于 2012-10-10T05:15:34.867 回答
4

在 Ruby 1.8.7 中,如果使用 collect 方法给出或没有给出块,它会返回一个数组。但是在 1.9 中,如果使用 collect 方法给出块,它只会返回数组。否则它将返回枚举器对象。从文档-

采集方法——

为枚举中的每个元素返回一个新数组,其中包含一次运行块的结果。如果没有给出块,则返回一个枚举器。

于 2012-10-10T05:21:55.893 回答
2

在 1.8.7 中,collect方法在应用于 File 对象时返回一个数组,而在 1.9.3 中,它返回一个enumeratorreverse方法只能应用于数组。

于 2012-10-10T05:16:08.043 回答
0

这在 1.8.7 中起作用的原因是,当您Enumerable#collect在 1.8.7 中不使用块调用时,它使用一个默认块,该块只返回其 arg,因此file.collect相当于file.collect {|x| x}which 返回文件中的行数组,在你可以调用Array#reverse`

在 1.9.x 中,Enumerable#collect没有块的调用会返回一个Enumerator. Enumerator 本身不支持#reverse,它的 mixin 也不支持Enumerable。所以,你会得到 NoMethodError。

如果您想以与任一版本兼容的方式编写此表达式,请使用#to_a而不是#collect.

output = File.open(text_file).to_a.reverse.join("<BR>")

于 2012-10-10T05:33:05.280 回答