gets.chomp внутри функции в ruby
Я прохожу "Изучай Руби трудный путь", и в упражнении 20 есть фрагмент кода, который я не понимаю. Я не понимаю, почему get.chomp вызывается для f в функции "print_a_line".
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)
Следовательно, я не понимаю, как производится вторая часть вывода. Я понимаю, что это первые 3 строки файла test.txt, которые передаются в код, но я не понимаю, как 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
2 ответа
Объект File f
отслеживает (ну, что-то, на что он ссылается, отслеживает), где он читает в файле. Думайте об этом как о курсоре, который продвигается, когда вы читаете в файле. Когда вы говорите f
в gets
, он читает, пока не достигнет новой строки. Они ключ в том, что f
помнит, где вы находитесь, потому что чтение продвинуло "курсор". chomp
звонок не входит в эту часть вообще. Так что каждый вызов f.gets
просто читает следующую строку файла и возвращает ее в виде строки.
chomp
манипулирует только строкой, которая возвращается f.gets
и не влияет на объект File.
Изменить: Чтобы завершить ответ: chomp
возвращает строку с удаленным завершающим символом новой строки. (Технически, он удаляет разделитель записей, но это почти никогда не отличается от новой строки.) Это происходит из Perl (AFAIK), и идея в том, что в принципе вам не нужно беспокоиться о том, что ваша конкретная форма получения ввода проходит мимо вас. символы новой строки или нет.
Если вы посмотрите на документацию для IO#gets
вы увидите, что он читает следующую строку из объекта ввода-вывода. Kernel#open
метод, который вы вызываете, вернет объект ввода-вывода, который имеет этот метод. #gets
метод - это то, что фактически продвигает вас на следующую строку. Это не имеет ничего общего с #chomp
на строке, которую он возвратил из чтения строки.