Ответ 1
Я видел много раз в рубиновых кодах непревзойденные
File.open
звонки
Можете ли вы привести пример? Я только когда-либо вижу это в коде, написанном новичками, которым не хватает "общих знаний на большинстве языков программирования, что поток для работы с файлами открыт-используется-закрывается".
Опытные рубисты либо явно закрывают свои файлы, либо более идиоматично используют блочную форму File.open
, которая автоматически закрывает файл для тебя. Его реализация в основном выглядит примерно так:
def File.open(*args, &block)
return open_with_block(*args, &block) if block_given?
open_without_block(*args)
end
def File.open_without_block(*args)
# do whatever ...
end
def File.open_with_block(*args)
yield f = open_without_block(*args)
ensure
f.close
end
Скрипты - это особый случай. Скрипты обычно работают так короткими и используют так мало дескрипторов файлов, что просто не имеет смысла их закрывать, так как операционная система все равно закроет их, когда выйдет script.
Нужно ли явно закрывать?
Да.
Если да, то почему GC автоклинирует?
Поскольку после того, как он собрал объект, вам больше не удастся закрыть файл, и, следовательно, вы будете утечка дескрипторов файлов.
Обратите внимание, что это не сборщик мусора, который закрывает файлы. Сборщик мусора просто выполняет любые финализаторы для объекта, прежде чем он его собирает. Так получилось, что класс File
определяет финализатор, который закрывает файл.
Если нет, то почему опция?
Потому что потерянная память дешевая, но потерянные файловые дескрипторы - нет. Поэтому нет смысла связывать время жизни файлового дескриптора с временем жизни некоторого фрагмента памяти.
Вы просто не можете предсказать, когда будет запущен сборщик мусора. Вы даже не можете предсказать, будет ли он работать вообще: если у вас никогда не закончится память, сборщик мусора никогда не запустится, поэтому финализатор никогда не запустится, поэтому файл никогда не будет закрыт.