File.open('file.txt') 与 File.open('file.txt').readlines
File.open('file.txt') vs. File.open('file.txt').readlines
我使用 File.open('file.txt').class
和 File.open('file.txt').readlines.class
检查过,前者 returns File 后者 returns 数组.
我理解这种差异,但如果我这样做:
File.open('file.txt').collect {|l| l.upcase}
=== File.open('file.txt').readlines.collect {|l| l.upcase}
它return是真的。那么当对象中的每个项目作为参数传递给块时,两个对象之间有什么区别吗?
而且,我假设在两个表达式中传递给块的参数都是文件中作为字符串的一行,这使得比较 return 为真,对吗?如果是这样,我如何知道在编写代码时将哪种参数传递给块?我是否必须检查文档或源代码之类的东西?
例如,我知道如何
['a','b','c'].each_with_index { |num, index| puts "#{index + 1}: #{num}" }
有效并认为这是理所当然的。但是我怎么知道第一个参数应该是数组中的每个项目,第二个参数应该是索引,而不是相反?
希望有道理,谢谢!
我会尽量让这个回复紧凑。
第二个问题 - 如果您对来自标准库的对象进行操作,您可以随时参考它们的文档,以便 100% 确定传递块时期望的参数。例如,您将多次在不同的数据结构 (Array, Hash, ...
) 上使用 each, select, map (etc ...)
等方法。在您习惯它们之前,您可能会在文档中找到关于它们的所有信息,例如:http://ruby-doc.org/core-2.2.0/Array.html
如果您在非核心数据结构上操作(例如来自您包含的 gem 的 class,您应该始终在 Github 上浏览它的文档或来源)。
第一个问题。使用不同的方法,结果可能相同,但在更深层次上可能存在一些差异。至于你的情况是基于文件。可以用两种方式处理读取文件内容。首先 - 将所有内容读入内存并对字符串数组进行操作,第二 - 按顺序读取文件行,这可能会持续更长时间但不会保留那么多内存。
在 irb 中进行一些 Ruby 自省。
irb(main):001:0> puts File.ancestors.inspect
[File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
这个结果向我们展示了 class 文件 class 继承自并且包含 class 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
这可能有点矫枉过正,但我们可以验证数组中是否存在可枚举方法。
irb(main):003:0> puts Array.ancestors.inspect
[Array, Enumerable, Object, Kernel, BasicObject]
在 Enumerable#each_with_index
中,参数的顺序与它们在方法名称本身中的顺序相同,首先是元素,然后是索引。与 each_with_object
.
相同
我使用 File.open('file.txt').class
和 File.open('file.txt').readlines.class
检查过,前者 returns File 后者 returns 数组.
我理解这种差异,但如果我这样做:
File.open('file.txt').collect {|l| l.upcase}
=== File.open('file.txt').readlines.collect {|l| l.upcase}
它return是真的。那么当对象中的每个项目作为参数传递给块时,两个对象之间有什么区别吗?
而且,我假设在两个表达式中传递给块的参数都是文件中作为字符串的一行,这使得比较 return 为真,对吗?如果是这样,我如何知道在编写代码时将哪种参数传递给块?我是否必须检查文档或源代码之类的东西?
例如,我知道如何
['a','b','c'].each_with_index { |num, index| puts "#{index + 1}: #{num}" }
有效并认为这是理所当然的。但是我怎么知道第一个参数应该是数组中的每个项目,第二个参数应该是索引,而不是相反?
希望有道理,谢谢!
我会尽量让这个回复紧凑。
第二个问题 - 如果您对来自标准库的对象进行操作,您可以随时参考它们的文档,以便 100% 确定传递块时期望的参数。例如,您将多次在不同的数据结构 (Array, Hash, ...
) 上使用 each, select, map (etc ...)
等方法。在您习惯它们之前,您可能会在文档中找到关于它们的所有信息,例如:http://ruby-doc.org/core-2.2.0/Array.html
如果您在非核心数据结构上操作(例如来自您包含的 gem 的 class,您应该始终在 Github 上浏览它的文档或来源)。
第一个问题。使用不同的方法,结果可能相同,但在更深层次上可能存在一些差异。至于你的情况是基于文件。可以用两种方式处理读取文件内容。首先 - 将所有内容读入内存并对字符串数组进行操作,第二 - 按顺序读取文件行,这可能会持续更长时间但不会保留那么多内存。
在 irb 中进行一些 Ruby 自省。
irb(main):001:0> puts File.ancestors.inspect
[File, IO, File::Constants, Enumerable, Object, Kernel, BasicObject]
这个结果向我们展示了 class 文件 class 继承自并且包含 class 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
这可能有点矫枉过正,但我们可以验证数组中是否存在可枚举方法。
irb(main):003:0> puts Array.ancestors.inspect
[Array, Enumerable, Object, Kernel, BasicObject]
在 Enumerable#each_with_index
中,参数的顺序与它们在方法名称本身中的顺序相同,首先是元素,然后是索引。与 each_with_object
.