Ответ 1
TL; DR
Все объекты File и IO хранятся в ObjectSpace.
Ответ
В классе ObjectSpace говорится:
Модуль ObjectSpace содержит ряд подпрограмм, которые взаимодействуют с средством сбора мусора и позволяют вам перемещать все живые объекты с помощью итератора.
Как я протестировал это
Я тестировал это на консоли на Ruby 1.9.3p194.
Тест-тест действительно прост. Идея состоит в том, чтобы иметь два объекта File с разными идентификаторами объектов, но только один из них напрямую доступен через переменную. Другой - "где-то там".
# Don't save a reference to the first object.
filename='/tmp/foo'
File.open(filename)
filehandle = File.open(filename)
Затем я исследовал различные способы взаимодействия с объектами File, даже если я не использовал явную ссылку на объект. Это было удивительно легко, как только я узнал об ObjectSpace.
# List all open File objects.
ObjectSpace.each_object(File) do |f|
puts "%s: %d" % [f.path, f.fileno] unless f.closed?
end
# List the "dangling" File object which we didn't store in a variable.
ObjectSpace.each_object(File) do |f|
unless f.closed?
printf "%s: %d\n", f.path, f.fileno unless f === filehandle
end
end
# Close any dangling File objects. Ignore already-closed files, and leave
# the "accessible" object stored in *filehandle* alone.
ObjectSpace.each_object(File) {|f| f.close unless f === filehandle rescue nil}
Заключение
Могут быть другие способы сделать это, но это тот ответ, который я придумал, чтобы поцарапать свой собственный зуд. Если вы знаете лучший способ, отправьте другой ответ. Мир станет для него лучшим местом.