永続化と評価の話
- 永続化
- プログラムで生成したデータが次回実行時でも利用できる
- マーシャル化
- バイナリデータ化し、loadやdumpすることができるようにすること
Timeオブジェクトをファイルへ保存する方法はいくつかあり、
- Time#strftimeで文字列として保存する
- Time.atクラスメソッドで10進数で経過秒数を出力
これらの方法で作成されたファイルはRuby以外のプログラムでも利用可能。しかし、Marshal.dumpメソッドを使って永続性を持たせると、Rubyだけで利用することになるので注意すること。
マーシャルオブジェクトの制限
- すべてのオブジェクトをマーシャルできるわけではない
- プログラムの実行状態に依存し、他のプロセスに持ち込めない
- 永続性が何かを一意に決められないもの(例:Fileオブジェクト)
- クラス名を持たないオブジェクト(復元時に元のクラス名が必要となるから)
- 保存する時にMarshalモジュールバージョンが異なるとデータを復元できない(TypeError例外を発生)
- Marshal::MAJOR_VERSIONの場合、バージョンが異なる時
- Marshal::MINOR_VERSIONの場合、現在のマイナーバージョンよりバージョンが大きい場合
さて、永続性のあるファイルを作りましょう。
t = Time.now() File.open("time.data", "rb") do |file| Marshal.dump(t, file) end
バイナリデータなので"rb"。"b"をつけるの忘れないように。
読み込むときは
require "pp" File.open("time.data", "wb") do |file| pp(Marshal.load(file)) end
PPライブラリは清書「pretty print」、オブジェクトを目で確認するためのライブラリ。デバッグに使うといいらしい。私は今まで"p"使ってたんだけど、"pp"を代わりに使ってもいいのか。じゃあ、irbを使おう。
irb(main):001:0> require "pp" => true irb(main):002:0> a = 1 => 1 irb(main):003:0> p a 1 => 1 irb(main):004:0> pp a 1 => nil
ん?ppだとnilが返ってくる・・・。調べたら、
pp(obj, out = $>, width = 79) -> object 指定されたオブジェクト obj を出力先 out に幅 width で出力します。出力先 out を返します。
aはオブジェクトじゃないから、nilだったんだ。そりゃそうだ、ppはオブジェクトのデバック用で使うんだよ。実際にコード書いてみないと、勘違いって見つけられないもんだなぁ。
評価
- 評価
- 式の最終的な値を求めることを評価するという
代入式の左辺だけが、評価抜きで未設定の変数を記述できる
a = 32 #ok func(b) #評価できないのでダメ
>>追記
「aはオブジェクトじゃないから、nilだったんだ。」本当は違う理由らしいです。調べるの宿題になってしまった・・・。