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 на строке, которую он возвратил из чтения строки.

Другие вопросы по тегам