我使用File.open('file.txt').class
和File.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}" }
工作并认为这是理所当然的。但是我怎么知道第一个参数应该是数组中的每个项目,第二个参数应该是索引,而不是反向?
希望有意义,谢谢!
答案 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
相同。