Marshalでオブジェクトを冷凍保存
Marshal.dumpでRubyのオブジェクトをファイルに保存し、Marshal.loadで戻すことができます。
1. 以下のプログラムではオブジェクトxをalice.dumpedというファイルにdumpで保存し、すぐ後でloadしてhelloメソッドを呼び出しています。
require 'pathname' class Rubyco def initialize(name='Rubyco') @name = name end def hello puts "Hello, #{@name}!" end end x = Rubyco.new('Alice') Pathname.new('alice.dumped').open('wb') do |f| Marshal.dump(x, f) end Pathname.new('alice.dumped').open('rb') do |f| Marshal.load(f).hello #=> Hello, Alice! end
2. ところで、保存されていたalice.dumpedを、Rubycoクラスを知らないプログラムがloadしたらどうなるのでしょう。
require 'pathname' Pathname.new('alice.dumped').open('rb') do |f| Marshal.load(f).hello end
以下のようなエラーになります。Rubycoなんていうクラスは知らないと言われてしまうようです。
b.rb:4:in `load': undefined class/module Rubyco (ArgumentError) from b.rb:4 from c:/ruby/lib/ruby/1.8/pathname.rb:798:in `open' from c:/ruby/lib/ruby/1.8/pathname.rb:798:in `open' from b.rb:3
3. ここで疑問が生じます。「Rubycoというクラスも、Classクラスのオブジェクトだったはず。それならMarshal.dumpできるのでは?」
require 'pathname' class Rubyco def initialize(name='Rubyco') @name = name end def hello puts "Hello, #{@name}!" end end Pathname.new('rubyco.dumped').open('wb') do |f| Marshal.dump(Rubyco, f) end
しかし、これを実行してもrubyco.dumpedに保存されるのはたった10バイト。名前しか保存されないようです(TypeErrorにはなりません)。
疑問:クラスのインスタンスはMarshalでdump/loadできないの?