TL; DR
すべてのファイルおよびIOオブジェクトはObjectSpaceに保存されます。
答え
ObjectSpaceクラスは次のように述べています。
ObjectSpaceモジュールには、ガベージコレクション機能と対話し、イテレータを使用してすべての生きているオブジェクトをトラバースできるようにする多数のルーチンが含まれています。
これをどのようにテストしたか
これをRuby1.9.3p194のコンソールでテストしました。
テストフィクスチャは本当に簡単です。アイデアは、異なるオブジェクトIDを持つ2つのFileオブジェクトを持つことですが、変数を介して直接アクセスできるのは1つだけです。もう1つは「どこかにある」です。
# 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}
結論
これを行う他の方法があるかもしれませんが、これは私が自分のかゆみを掻くために思いついた答えです。より良い方法を知っている場合は、別の回答を投稿してください。世界はそれにとってより良い場所になるでしょう。