Ruby
Ruby2.3
Ruby2.4

【動作確認】RubyのFile.open()にブロックを与えると処理後にクローズしてくれるって本当?

はじめに

File.openの気になった点を解決するべく色々と動かしてみた。

動機の気になったやつら(前回記事)
* 【実際に動かしてみた】RubyのFile.openのブロックによるリソース管理について - Qiita
* RubyのFile.openのブロックによるリソース管理について - OSのようなもの

実行

とりあえず色々なパターン動かしてみた。

file = File.open('test.txt')
p file
# => <File:test.txt>

file = File.open('test.txt')
file.close
p file
# => <File:test.txt (closed)>
p File.open('test.txt')
# => #<File:test.txt>

p File.open('test.txt').close
# => nil

file = nil
p (file = File.open('test.txt')).close
p file
# => #<File:test.txt (closed)>

file = nil
File.open('test.txt') { |f| file = f }
p file
# => #<File:test.txt (closed)>

p File.open('test.txt').each {}
# => #<File:test.txt>

p File.open('test.txt').each {}.close
# => nil

file = nil
(file = File.open('test.txt').each {}).close
p file
# => #<File:test.txt (closed)>

file = nil
File.open('test.txt') { |f| file = f }.each {}
p file
# => `each': closed stream (IOError)

結果

file = nil
File.open('test.txt') { |f| file = f }
p file
# => #<File:test.txt (closed)>

File.open()にブロックを与えると、ブロック処理終了のタイミングでファイルクローズ(File.close)していることが分かった。

バージョンは違いますが、動作自体はリファレンス singleton method File.new (Ruby 2.5.0) に書いてあるんだからそうですよね。

path で指定されるファイルをオープンし、File オブジェクトを生成して 返します。

path が整数の場合はファイルディスクリプタとして扱い、それに対応する File オブジェクトを生成して返します。IO.open と同じです。 ブロックを指定して呼び出した場合は、File オブジェクトを引数として ブロックを実行します。ブロックの実行が終了すると、ファイルは自動的に クローズされます。ブロックの実行結果を返します。

Rubyバージョン

$ ruby -v
ruby 2.3.1p112 (2016-04-26 revision 54768) [x86_64-darwin16]

$ ruby -v
ruby 2.4.1p111 (2017-03-22 revision 58053) [x86_64-darwin16]

参考文献