Между этими тремя вариантами есть важные различия.
File.open("file").each_line { |line| puts line }
File.open
открывает локальный файл и возвращает объект файла
- файл остается открытым, пока вы не наберете
IO#close
для него
open("file").each_line { |line| puts line }
Kernel.open
смотрит на строку, чтобы решить, что с ней делать.
open(".irbrc").class # => File
open("http://google.com/").class # => StringIO
File.open("http://google.com/") # => Errno::ENOENT: No such file or directory - http://google.com/
Во втором случае объект StringIO
, возвращаемый Kernel#open
, фактически содержит содержимое http://google.com/. Если Kernel#open
возвращает объект File
, он остается открытым, пока вы не вызовете IO#close
.
IO.foreach("file") { |line| puts line }
IO.foreach
открывает файл, вызывает указанный блок для каждой прочитанной строки и затем закрывает файл.
- Вам не нужно беспокоиться о закрытии файла.
File.read("file").each { |line| puts line }
Вы не упомянули этот выбор, но я бы использовал его в большинстве случаев.
File.read
полностью читает файл и возвращает его в виде строки.
- Вам не нужно беспокоиться о закрытии файла.
- По сравнению с
IO.foreach
ясно, что вы имеете дело с файлом.
- Сложность памяти для этого O (n). Если вы знаете, что имеете дело с небольшим файлом, это не является недостатком. Но если это может быть большой файл, и вы знаете, что ваша память может быть меньше, чем O (n), не используйте этот выбор.
Сбой в этой ситуации:
s= File.read("/dev/zero") # => never terminates
s.each …
п
ri - это инструмент, который показывает вам документацию по ruby. Вы используете это как на своей оболочке.
ri File.open
ri open
ri IO.foreach
ri File#each_line
С этим вы можете найти почти все, что я написал здесь и многое другое.