我正在经历“以艰难的方式学习Ruby”,而在练习20中,有一段我不理解的代码片段。我不明白为什么在函数“print_a_line”中调用f来调用f。
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
答案 0 :(得分:7)
File对象f
跟踪文件中读取的位置(以及它引用的内容跟踪)。您可以将其视为在文件中读取时前进的光标。当您将f
告诉gets
时,它会一直显示,直到它到达新行。关键是f
会记住你所处的位置,因为读数会提升光标。" chomp
来电根本不会进入此部分。因此,f.gets
的每次调用只读取文件的下一行并将其作为字符串返回。
chomp
仅操纵f.gets
返回的字符串,对File对象没有影响。
编辑:要完成答案:chomp
将返回删除了尾随换行符的字符串。 (从技术上讲,它删除了记录分隔符,但这几乎与新行不同。)这来自Perl(AFAIK),其想法是,基本上你不必担心你的特定形式的输入是否是是否传递换行符。
答案 1 :(得分:2)
如果您查看IO#gets
的{{3}},您会看到它从IO对象中读取 next 行。您正在调用的Kernel#open
方法将返回具有该方法的IO对象。 #gets
方法实际上是将您带到下一行。它与读取该行返回的字符串上的#chomp
无关。