4

我正在阅读“Learn Ruby the Hard Way”,在练习 20 中有一段我不理解的代码。我不明白为什么在函数“print_a_line”中对 f 调用gets.chomp。

input_file = ARGV.first

def print_all(f)
  puts f.read
end

def rewind(f)
  f.seek(0)
end

def print_a_line(line_count, f)
  puts "#{line_count}, #{f.gets.chomp}"
end

current_file = open(input_file)

puts "First let's print the whole file:\n"

print_all(current_file)

puts "Now let's rewind, kind of like a tape."

rewind(current_file)

puts "Let's print three lines:"

current_line = 1
print_a_line(current_line, current_file)

current_line = current_line + 1
print_a_line(current_line, current_file)

current_line = current_line + 1
print_a_line(current_line, current_file)

因此,我不明白输出的第二部分是如何产生的。我知道这是传递到代码中的 test.txt 文件的前 3 行,但我不明白 f.gets.chomp 是如何产生这个的。

$ ruby ex20.rb test.txt
First let's print the whole file:
This is line 1
This is line 2
This is line 3
Now let's rewind, kind of like a tape.
Let's print three lines:
1, This is line 1
2, This is line 2
3, This is line 3
4

2 回答 2

7

File 对象f跟踪它在文件中读取的位置(嗯,它引用的东西会跟踪)。可以把它想象成一个在你阅读文件时前进的光标。当您告诉fto 时gets,它会一直读取到新行。他们的关键是f记住你在哪里,因为阅读推进了“光标”。chomp呼叫根本不进入这部分。所以每次调用f.gets只读取文件的下一行并将其作为字符串返回。

chomp只是操作返回的字符串,对f.getsFile 对象没有影响。

编辑:完成答案:chomp返回删除了尾随换行符的字符串。(从技术上讲,它删除了记录分隔符,但这几乎与换行符不同。)这来自 Perl(AFAIK),其想法是基本上你不必担心你的特定形式的输入是否传递给你换行符与否。

于 2014-12-12T06:52:20.060 回答
2

如果您查看 的文档IO#gets您会看到它从 IO 对象读取下一行。Kernel#open您调用的方法将返回具有该方法的 IO 对象。该#gets方法实际上将您推进到下一行。#chomp它与读取该行返回的字符串无关。

于 2014-12-12T05:58:53.063 回答