Rubyコードで比類のないFile.open
呼び出しを何度も見ました
例を挙げていただけますか?「ほとんどのプログラミング言語で、ファイルを操作するためのフローがopen-use-closeであるという一般的な知識」を欠いている初心者によって書かれたコードでは、これだけしか目にしません。
経験豊富なRubyistは、ファイルを明示的に閉じるか、またはより慣用的に、のブロック形式を使用し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
クラスがファイルを閉じるファイナライザを定義していることが起こります。
そうでない場合、なぜオプションですか?
無駄なメモリは安いですが、無駄なファイル記述子はそうではありません。したがって、ファイル記述子の存続期間をメモリのチャンクの存続期間に関連付けることは意味がありません。
あなたは、単に予測できないとき、ガベージコレクタが実行されます。あなたも予測することができないならば、それは実行されるすべてで:あなたはメモリが不足したことがない場合は、ガベージコレクタが実行されることはありません、したがって、ファイナライザが実行されることはありませんので、ファイルを閉じことはありません。