Я много раз видел в рубиновых кодах не совпадающих File.open
звонки
Можете привести пример? Я только когда-либо видел, что в коде, написанном новичками, которым не хватает , "в большинстве языков программирования" общеизвестно, что поток для работы с файлами открыт-используется-закрыт ".
Опытные Rubyists либо явно закрывают свои файлы, либо, иными словами, используют блочную форму 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
Скрипты - это особый случай. Сценарии обычно выполняются настолько короткими и используют так мало файловых дескрипторов, что закрывать их просто не имеет смысла, так как операционная система все равно закроет их при выходе из сценария.
Нам нужно явно закрыть?
Да.
Если да, то почему GC автоматически закрывается?
Поскольку после того, как он соберет объект, у вас больше не будет возможности закрыть файл, и, таким образом, вы потеряете дескрипторы файлов.
Обратите внимание, что не сборщик мусора закрывает файлы. Сборщик мусора просто выполняет любые финализаторы для объекта перед тем, как его собрать. Так уж получилось, что класс File
определяет финализатор, который закрывает файл.
Если нет, то почему опция?
Потому что потраченная впустую память дешева, а дескрипторы потраченных файлов - нет. Следовательно, не имеет смысла связывать время жизни файлового дескриптора с временем жизни некоторого куска памяти.
Вы просто не можете предсказать , когда запустит сборщик мусора. Вы даже не можете предсказать , если вообще запустится : если у вас никогда не кончится память, сборщик мусора никогда не запустится, поэтому финализатор никогда не запустится, поэтому файл никогда не будет быть закрытым.