Project

General

Profile

Actions

Bug #12554

closed

yamlに渡すファイルポインタを自分でcloseしないと動作が変

Added by uy (西行寺 うゆ) over 8 years ago. Updated over 8 years ago.

Status:
Rejected
Assignee:
-
Target version:
-
ruby -v:
ruby 2.3.1p112 (2016-04-26 revision 54768) [i386-mswin32_100]
[ruby-dev:49716]

Description

rubyのファイルポインタは、スコープを抜けたら処理系側でcloseされているものと思ったんですが
yamlで読み書きを行う場合に動作がおかしいような気がします

このスクリプトを実行すると、それなりの確率で以下のエラーが出て、
test.yamlのデータが変です


require"yaml"
def func
file = "test.yaml"
data = YAML.load_file( file )
r = rand(99999)
data ||={}
data[r] ||=[]
data[r] << rand(99999)

# 問題個所
YAML.dump( data, open( file , 'w') )


# 自分でcloseすると平気
#
# f = open( file , 'w')
# YAML.dump( data , f ) ;
# f.close

end
1000.times do |n|
  print n , " "
  func
end

C:/Ruby/lib/ruby/2.3.0/psych.rb:377:in `parse': (test.yaml): did not find expected key while pa
rsing a block mapping at line 2 column 1 (Psych::SyntaxError)
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:377:in `parse_stream'
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:325:in `parse'
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:252:in `load'
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:471:in `block in load_file'
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:471:in `open'
        from C:/Ruby/lib/ruby/2.3.0/psych.rb:471:in `load_file'
        from -:4:in `func'
        from -:11:in `block in <main>'
        from -:10:in `times'
        from -:10:in `<main>'

Files

test.yaml (270 Bytes) test.yaml uy (西行寺 うゆ), 07/05/2016 01:30 PM

Updated by usa (Usaku NAKAMURA) over 8 years ago

西行寺 うゆ wrote:

rubyのファイルポインタは、スコープを抜けたら処理系側でcloseされているものと思ったんですが

それは誤解です。
参照されなくなったFileオブジェクトは、GCされる時にcloseされる可能性はありますが、
それはいつになるのか普通は予測困難ですので、用が済んだらちゃんと閉じられるように
コードを書いてください。

Updated by uy (西行寺 うゆ) over 8 years ago

ありがとうございます。
GCのcloseに頼ったコードを書いていたみたいです。
気を付けたいと思います。

Updated by yugui (Yuki Sonoda) over 8 years ago

  • Status changed from Open to Rejected

そういうときのためにブロック付きメソッドがあるので、次のように書いてください。

open( file , 'w') {|f| YAML.dump(data , f ) }

Actions

Also available in: Atom PDF

Like0
Like0Like0Like0