Use of Marshal with wxruby classes

Is it possible to use Marshal with wxruby classes to serialize an
application’s state?

I tried a minimal example of simply serializing a minimal frame object,
and
I get the error “no marshal_dump is defined for class MinimalFrame”.

I don’t fully understand this because I also tried another minimal
example
of dumping a class which did not defined a marshal_dump, and it worked
fine. Is there some reason this has been disabled in wxruby classes?
Sorry, I picked up ruby a few days ago so I may be missing something
obvious.

Here’s a test program showing that the simple class will serialize but
the
simple frame will not.

#!/usr/bin/env ruby

require ‘wx’
include Wx

class MinimalClass
def initialize
@data = 1234
end

def save
File.open(“dump-class”,“w+”) do |f|
Marshal.dump(self, f)
end
end

end

class MinimalFrame < Frame
def initialize(title)
# The main application frame has no parent (nil)
super(nil, :title => title, :size => [ 700, 400 ])
@data = 1234
end

def save
File.open(“dump-frame”,“w+”) do |f|
Marshal.dump(self, f)
end
end

end

App.run do

obj = MinimalClass.new
obj.save

self.app_name = ‘Minimal’
frame = MinimalFrame.new(“Minimal wxRuby App”)
frame.save
end

Robert A. wrote:

classes? Sorry, I picked up ruby a few days ago so I may be missing
something obvious.

It’s not completely obvious, but I’m fairly sure what’s happening is
this: Marshal is able to store ordinary ruby objects that are composed,
in the end, of core ruby types, like Float, Fixnum, String, Hash etc. So
if you write any class just in ruby, Marshal can serialise its
instances.

Objects like a Wx::Frame, or any other ruby object that comes from a
ruby C extension is different. It’s a wrapper or pointer to compiled
code (a C++ object in wxRuby). Ruby can’t serialise and restore such
objects without extra information.

Not sure why you’d want to serialise a Wx::Frame. If you’re interested
in storing and restoring the size, position or layout of a Frame between
runs, just store that information and a hash and serialise it, and then
when the “same” window is re-opened, Marshal.load the hash and restore
the settings. The first few methods in this real-life app do this sort
of thing:

http://weft-qda.rubyforge.org/svn/trunk/weft-qda/lib/weft/wxgui/inspectors.rb

hth
alex

Hello Alex and Robert,

Sorry I wasn’t able to respond when I saw this, cause it takes a bit of
explanation of the ways Marshal works, to fully express what is being
done,
and why Wx::Frame can’t be saved through Marshaling.

Alex, to a certain extent is correct. However, the main thing to note
here,
is that Marshal simply doesn’t know how to “dump” the information within
a
Class, that doesn’t explicitly have a marsha_dump method defined on it.
The
primary Ruby objects / classes, such as Hash, Array, Fixnum and Bignum
have
basic initialization techniques behind them, that Marshal already knows
about, and how to store them in a format that it can later re-load up.

The problem when it comes to Extensions, such as wxRuby, Ruby-Gnome/GTK,
RubyQT, Fox and so forth, is that these are formats that it doesn’t know
about, and doesn’t know how to save the said data. And it’s a good
thing as
well, since most of that information, is dynamically created whenever
the
application creates them. No two runnings have the same information. A
perfect comparison for this, is the handle for a Window/Frame/Widget.
No
two handles are going to be the same. As with Memory actually
allocated, no
two allocated addresses will be the same between runnings, as the OS
finds
where it can for the Memory, and then returns that information back to
the
executing program.

However, the stuff that is consistent, such as size, title or style for
a
Window/Frame/Widget, or the actual data stored within a Memory Address,
can
be saved, if you supply the marshal_dump method on the class, so Marshal
knows how to dump, and restore the data. As with marshal_dump, there’s
also
a method called marshal_load. The marshal_dump should return a string
that
has the specific data in it, in which you can write to a file, the same
goes
for marshal_load(), it’ll be given the string that marshal_dump returns,
so
that you can restore it.

So, you can go the route as I have suggested it, or you can do like Alex
suggest, and just store the information in a Hash, or an Array, and then
Marshal that to load, and save the data. Hope this gives you a little
more
insight into how the Marshaling is handled.

L8ers,

Mario S.