ょゎさんとこで発覚した現象だが、 Ruby CVS HEAD で tDiary を動かすとデータファイルが消える。
結論から言うと原因はこれ。 このコードは tdiary/default.rb 1.23 で入っているので、 tDiary 1.5.3 以降の全バージョンで発現すると思われる。
--- tdiary/defaultio.rb 2 Aug 2004 12:54:12 -0000 1.1.1.2
+++ tdiary/defaultio.rb 24 Mar 2005 02:11:52 -0000 1.2
@@ -189,8 +189,8 @@
while l = fh.gets( "\n.\n" )
begin
headers, body = TDiary::parse_tdiary( l )
- style = headers['Format'] || 'tDiary'
- diary = eval( "#{style( style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
+ _style = headers['Format'] || 'tDiary'
+ diary = eval( "#{style( _style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
diary.show( headers['Visible'] == 'true' ? true : false )
diaries[headers['Date']] = diary
rescue NameError
該当コードを発見する方法…… ruby に -d をつける
しかし、例外が起こるとファイルが消えるというのもそれはそれで変だな。 何が起こっているのだろう。
あー、わかった。
def restore( fh, diaries )
:
(前半略)
:
# read and parse diary
while l = fh.gets( "\n.\n" )
begin
headers, body = TDiary::parse_tdiary( l )
style = headers['Format'] || 'tDiary'
diary = eval( "#{style( style )}::new( headers['Date'], headers['Title'], body, Time::at( headers['Last-Modified'].to_i ) )" )
diary.show( headers['Visible'] == 'true' ? true : false )
diaries[headers['Date']] = diary
rescue NameError
rescue
raise
end
end
ensure
fh.flock( File::LOCK_UN )
end
end
style(style) の行で NoMethodError が起こるが それは NameError の下位クラスなので rescue されてなかったことになり、 ファイルには記録がないことになる。 で、消してるのはここか。
module tDiary
class DefaultIO
def transaction( date )
:
:
if diaries.empty?
File::delete( @dfile )
# also delete parser cache
@tdiary.store_parser_cache( date, nil, nil)
end
ちなみに、ここはロックされてないように見える。 restore から store の間に別のプロセスが 記事を追加していたら、それを消してしまう可能性があるのではないか。 ……とは言え、相当なレアケースだからどうでもいいような気もするな。
(16:45)