File.openの読み込み形式について
RubyのFile.openでは、第一引数にファイルのパスを第二引数にopenするモードを指定します。
Rubyのリファレンスを見てみると、次のように書いています。
fileをオープンして、Fileオブジェクトを返します。 modeは、以下の文字列か整数(File::Constantsモジュールの定数の論理和)を指定します。省略時は"r"が指定されたものとみなします。
"r", RDONLY: ファイルを読み込みモードでオープンします。
"w", WRONLY|CREAT|TRUNC: ファイルを書き込みモードでオープンします。オープン時にファイルがすでに存在していれば その内容を空にします。
"a", WRONLY|CREAT|APPEND: ファイルを書き込みモードでオープンします。出力は常にファイルの末尾に追加されます *1"+" があれば、ファイルは読み書き両用モード(RDWR)でオープンされます。
"r+": ファイルの読み書き位置は先頭にセットされます。
プログラミング言語 Ruby リファレンスマニュアル
"w+": "r+"と同じですが、オープン時にファイルがすでに存在していればその内容を空にします。
"a+": "r+"と同じですが、オープン時にファイルがすでに存在していれば読み書き位置がファイルの末尾にセットされます。
これらのいずれに対しても"b"フラグを("r+b"のように)つけることができます(整数なら File::BINARY)。この場合、バイナリモードでオープンします(ただし、システムがテキスト/バイナリでファイルを区別する場合に限ります)
さて、何でこんな話をしたかというと、前述している「typo」でtheme editorでcssを編集したら、
保存がおかしくなる、という現象があったからです。
で、色々調べてみるとこういうこういう記述を見つけました。
app/controllers/admin/themes_controller.rbの53行目 if File.writable? path + filename case request.method when :post theme = File.new(path + filename, "r+") theme.write(params[:theme_body]) theme.close flash[:notice] = _("File saved successfully") zap_theme_caches end else
つまりモードを"r+"で読み込んでいます。
前述の引用を見ると"r+"は読み書き位置が先頭になると書いています。
つまり、すでに保存している文字数>今回保存する文字数となったときに、
今回の分を保存しきっても、前回の分が後ろに残ってしまいそれがおかしくなる原因だったようです。
なので、こう直せば動くと思います。
app/controllers/admin/themes_controller.rbの53行目 if File.writable? path + filename case request.method when :post - theme = File.new(path + filename, "r+") + theme = File.new(path + filename, "w+") theme.write(params[:theme_body]) theme.close flash[:notice] = _("File saved successfully") zap_theme_caches end else