# How to store/load persistent data?

**URL:** <https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507>\
**Category:** Ruby\
**Created:** [September 4, 2006, 7:32pm UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507 "2006-09-04T19:32:01Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 4, 2006, 7:32pm UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/1 "2006-09-04T19:32:01Z")

</div>

Hello!

In my previous life (in perl-world) I was used to store persistent data  
with Data::Dumper and load it back with “require ‘/path/to/file’”.

Now I’m learing ruby and started my first toy-project. I must admit  
that  
I am not very familiar with OO techniques.

AFAICS, the ruby way to store persistent data is YAML. Saving an object  
with YAML.dump() works like a charm. But I have trouble to read them  
back with YAML.load(). For some reason, the initialize() method of the  
loaded object doesn’t get called. I don’t understand how an object can  
properly spring in existance without the initialize method? For  
example,  
I allocate a TkCanvas in the initialize() method. Such an object can  
not  
be loaded back properly, IMHO.

I have one more problem with such an object: There’s no destructor.  
Should  
such an object get out of scope, how do I make sure the allocated canvas  
is destroyed properly?

I’m sorry if this is a stupid question, but I am new to both, ruby and  
OO.  
Please can somebody give an explanation how such an object is handled in  
the ruby-world?

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 5, 2006, 12:16am UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/2 "2006-09-05T00:16:31Z")

</div>

On Sep 4, 2006, at 1:30 PM, Josef W. wrote:

> AFAICS, the ruby way to store persistent data is YAML. Saving an  
> object  
> with YAML.dump() works like a charm. But I have trouble to read them  
> back with YAML.load(). For some reason, the initialize() method of  
> the  
> loaded object doesn’t get called. I don’t understand how an object  
> can  
> properly spring in existance without the initialize method?

Well the general purpose of initialize is to set up some state /  
instance variables. That’s exactly what the serialized form of the  
object keeps track of anyway.

> For example,  
> I allocate a TkCanvas in the initialize() method. Such an object  
> can not  
> be loaded back properly, IMHO.

Some things aren’t serializable in a sane way, that’s just a fact of  
life.

> I have one more problem with such an object: There’s no  
> destructor. Should  
> such an object get out of scope, how do I make sure the allocated  
> canvas  
> is destroyed properly?

The garbage collector makes sure that the memory used by objects that  
go out of scope is reclaimed.

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 5, 2006, 11:54pm UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/3 "2006-09-05T23:54:42Z")

</div>

On Tue, Sep 05, 2006 at 07:10:28AM +0900, Logan C. wrote:  
[…]

> > AFAICS, the ruby way to store persistent data is YAML. Saving an  
> > object with YAML.dump() works like a charm. But I have trouble to  
> > read them back with YAML.load(). For some reason, the initialize()  
> > method of the loaded object doesn’t get called. I don’t understand  
> > how an object can properly spring in existance without the initialize  
> > method?
> 
> Well the general purpose of initialize is to set up some state /  
> instance variables. That’s exactly what the serialized form of the  
> object keeps track of anyway.

But what to do when an object needs some resources (this might be a  
file/database opened, or, as in my case, a TkCanvas)?

> > For example, I allocate a TkCanvas in the initialize() method. Such  
> > an object can not be loaded back properly, IMHO.
> 
> Some things aren’t serializable in a sane way, that’s just a fact of  
> life.

I understand that this is not serializable. But wouldn’t it be good  
to have a chance to reconstruct a new (identical) object from the  
reloaded  
state/instance variables? It need not be the original initialize()  
method.  
It would probably be even better would YAML invoke yaml\_initialize() or  
something.

> > I have one more problem with such an object: There’s no destructor.  
> > Should such an object get out of scope, how do I make sure the  
> > allocated canvas is destroyed properly?
> 
> The garbage collector makes sure that the memory used by objects that  
> go out of scope is reclaimed.

It is clear to me that the ruby object is removed by the garbage  
collector. But it is not clear what happens to other recources (a  
TkCanvas in this case) allocated by this object. Check this out:

#! /usr/bin/ruby

require ‘tk’

root=TkRoot.new

class Foo  
def initialize  
canvas = TkCanvas.new.pack  
rect = TkcRectangle.new(canvas, 0, 0, 50, 50, “fill”=\>“white”)  
end  
end

begin  
x=Foo.new()  
end

GC.start

# Object destroyed but canvas and rectangle are still alive

Tk.mainloop

I can’t see a solution for this problem since I am a novice for  
ruby/OO/Tk.  
How do you gurus handle such situations?

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 6, 2006, 12:18am UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/4 "2006-09-06T00:18:44Z")

</div>

On Sep 5, 2006, at 5:40 PM, Josef W. wrote:

> end
> 
> GC.start
> 
> # Object destroyed but canvas and rectangle are still alive
> 
> Tk.mainloop
> 
> I can’t see a solution for this problem since I am a novice for  
> ruby/OO/Tk.  
> How do you gurus handle such situations?

That just means that there is still a reference to those objects.  
When all the references go away, then and only then ruby will collect  
them (if it needs to.)

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 6, 2006, 12:22am UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/5 "2006-09-06T00:22:44Z")

</div>

Josef W. wrote:

> class Foo  
> GC.start
> 
> # Object destroyed but canvas and rectangle are still alive
> 
> Tk.mainloop
> 
> I can’t see a solution for this problem since I am a novice for ruby/OO/Tk.  
> How do you gurus handle such situations?

There is a well-known Ruby idiom for coding block-scoped resources.  
There used to be a good page describing this in RubyGarden but alas that  
page seems to have disappeared. Anyway, here’s the general example from  
that page:

> def Resource.open( identifier ) # :yield: resource  
> resource = Resource.new( identifier )  
> if block\_given?  
> begin  
> yield resource  
> ensure  
> resource.close  
> end  
> else  
> return resource  
> end  
> end

That is, create/open/whatever the resource is and yield to a block.  
Within the block use the resource. When the block returns, close/destroy  
the resource. The open method in the IO class is prototypical.

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 6, 2006, 7:18pm UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/6 "2006-09-06T19:18:37Z")

</div>

On Wed, Sep 06, 2006 at 07:17:46AM +0900, Timothy H. wrote:

> Josef W. wrote:

> > ```
> > ensure
> > resource.close
> > end
> > else
> > return resource
> > end
> > 
> > ```
> > 
> > end
> 
> That is, create/open/whatever the resource is and yield to a block.  
> Within the block use the resource. When the block returns, close/destroy  
> the resource. The open method in the IO class is prototypical.

I am aware of this idiom. This idiom works very well if you have a  
strictly  
hierachical call structure.

But I just can’t see how this can help when dealing with Tk (especially  
with canvas items). In this case, objects are created and destroyed  
asynchronously. The block that creates a new widget has to return  
_before_ the widget is destroyed.

Of course, with widgets like TkDialog, this idiom would work very well  
since dialog-\>Show() blocks until the widget is destroyed. OTOH,  
TkDialog  
don’t need this idiom since it is already destroyed when its Show method  
returns.

---

<div class="post-metadata">

**Author:** ![Josef\_W](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/c0e974/32.png) [@Josef\_W](https://www.ruby-forum.com/u/Josef_W)\
**Post date:** [September 6, 2006, 6:54pm UTC](https://www.ruby-forum.com/t/how-to-store-load-persistent-data/67507/7 "2006-09-06T18:54:34Z")

</div>

On Wed, Sep 06, 2006 at 07:10:18AM +0900, Logan C. wrote:

> On Sep 5, 2006, at 5:40 PM, Josef W. wrote:

> > 
> 
> That just means that there is still a reference to those objects.  
> When all the references go away, then and only then ruby will collect  
> them (if it needs to.)

Exactly. The Tk library holds the references. To get rid of them, I  
need to call canvas.delete(rect) for the rectangle and canvas.destroy  
for the canvas. When I add those two calls, they disappear without  
messing with the GC.
