File.open('file.txt')与File.open('file.txt')。readlines

时间:2015-05-23 09:25:31

标签: ruby iterator

我使用File.open('file.txt').classFile.open('file.txt').readlines.class进行了检查,前者返回文件,后者返回数组

我理解这种差异,但如果我做了类似的事情:

    File.open('file.txt').collect           {|l| l.upcase} 
=== File.open('file.txt').readlines.collect {|l| l.upcase}

它返回true。那么当对象中的每个项目作为参数传递给块时,两个对象之间是否存在任何差异?

而且,我假设在两个表达式中传递给块的参数都是文件中的一行,这使得比较返回true,这是正确的吗?如果是这样,我怎么知道在编写代码时会将哪种参数传递给块?我是否必须检查文档或源代码?

例如,我知道如何

['a','b','c'].each_with_index { |num, index|  puts "#{index + 1}: #{num}" }  

工作并认为这是理所当然的。但是我怎么知道第一个参数应该是数组中的每个项目,第二个参数应该是索引,而不是反向?

希望有意义,谢谢!

3 个答案:

答案 0 :(得分:1)

在irb中做一些Ruby内省很自在。

irb(main):001:0> puts File.ancestors.inspect
[File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]

此结果显示了File类继承的类,包括类Enumerable的方法。那么从File.readlines返回什么对象?我认为是一个阵列,让我们来看看。

ri File.readlines
IO.readlines(name, sep=$/ [, open_args])     -> array
IO.readlines(name, limit [, open_args])      -> array
IO.readlines(name, sep, limit [, open_args]) -> array

这可能有点过分,但我们可以验证数组中是否存在Enumerable方法。

irb(main):003:0> puts Array.ancestors.inspect
[Array, Enumerable, Object, Kernel, BasicObject]

答案 1 :(得分:0)

我会尝试尽可能简化此回复。

第二个问题 - 如果您对来自标准库的对象进行操作,您可能总是参考他们的文档,以便100%确定传递块时期望的参数。例如,您将在不同的数据结构(each, select, map (etc ...))上多次使用Array, Hash, ...等方法。在您习惯它们之前,您可以在文档中找到有关它们的所有信息,例如:http://ruby-doc.org/core-2.2.0/Array.html

如果您在非核心数据结构上运行(例如,包含来自gem的类,您应该始终在Github上浏览它的文档或来源)。

第一个问题。使用不同方法时结果可能相同,但在更深层次上可能存在一些差异。就你的情况而言,基于文件。可以以两种方式处理读取文件内容。首先 - 将所有内容读入内存并对字符串数组进行操作,第二次 - 按顺序读取文件行,这可能会持续更长时间,但不会保留尽可能多的内存。

答案 2 :(得分:0)

Enumerable#each_with_index中,参数的顺序与它们在方法名称本身中的顺序相同,首先是元素,然后是索引。与each_with_object相同。