# Persistent Objects with Ruby - simple beginning

**URL:** <https://www.ruby-forum.com/t/persistent-objects-with-ruby-simple-beginning/226032>\
**Category:** Ruby\
**Created:** [December 16, 2008, 7:31pm UTC](https://www.ruby-forum.com/t/persistent-objects-with-ruby-simple-beginning/226032 "2008-12-16T19:31:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![Casimir\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/839c29/32.png) [@Casimir\_P](https://www.ruby-forum.com/u/Casimir_P)\
**Post date:** [December 16, 2008, 7:31pm UTC](https://www.ruby-forum.com/t/persistent-objects-with-ruby-simple-beginning/226032/1 "2008-12-16T19:31:12Z")

</div>

Object persistence, I want it, without SQL or other schemes that could  
be  
implemented in ruby and somewhat automated instead. Smalltalk and Squeak  
inspired. Objects exist, no CRUD or ‘saving’ or ‘writes’.

So, as an attempt to I made this Storage singleton and Storable -class.  
(code at end or at [http://pastie.org/340631](http://pastie.org/340631) )

It is very simple and crude. I am not a computer scientist, more like an  
artist with tourettes.

Nevertheless, I was hoping to get input. I think perhaps the next step  
would be changing this into a module.

If time and skills permit it, it would be fun to make a ruby fork with  
persistence similar to Prevayler (mem + snapshots&transactions record)  
or  
Squeak (save image of VM), like DHH suggested in 2k8 Rubyconf:

Persruby.

Have fun,  
Casimir

#start START  
#See example at end of file. Paste into IRB or save as file and load to  
test.

class Storable

#Marshals objects, creates meta-data labels  
#Intent: abstracts marshaling, unique filename, structured labeling  
#ORM-like?

attr\_accessor :filename, :label, :label\_str, :user, :private, :tags,  
:description

def initialize(given\_name = “unknown\_object”)  
@creation\_time = Time.now.tv\_sec  
@given\_name = given\_name.to\_s  
@tags = “storable” #for metainfo  
@description = “desc”

```
#generate label
self.labelize()

#generate filename
filename_str = @given_name +"."+ self.object_id.to_s

```

# +“.”+ @creation\_time.to\_s

```
filename_str = filename_str.gsub(" ", "_")
@filename = filename_str #why this again?!?

```

end #init

def labelize #sets storable’s attribs for the purposes of labeling  
them  
@label = {  
# - object class  
:class =\> self.class.to\_s,  
# - given name  
:given\_name =\> @given\_name,  
# - object id  
:object\_id =\> self.object\_id.to\_s,  
# - time created  
:time\_created =\> @creation\_time.to\_s, #seconds since epoch  
# - owner  
:user =\> “user”,  
# - tags\_str  
:tags =\> @tags.to\_s,  
# - description\_str  
:description =\> @description.to\_s  
# - date now (filesystem?)  
}

```
#Label packaged to a String -form
@label_str = ""
self.label.each_pair { |key, val|
  #each pair into string delimited by |
  label_str << key.to_s + "|" + val.gsub("|", "!").to_s + "\n"
}

```

end #end labelize

def put\_into\_storage  
#marshals, labels and stores object in Storage  
#future args command\_msg\_str  
#set object label  
labelize()  
#marshal object  
package = Marshal.dump(self)  
#store label and object  
#resolve ‘storage path’  
relative\_path\_str = “serialized.” + self.class.to\_s + “.” +  
@filename.to\_s

```
#store label
lbl_path = relative_path_str + ".label"
Storage.store(lbl_path, @label_str)

#store file
Storage.store(relative_path_str, package)

```

end

def self.find\_by\_fname(fname) #not implemented  
found = nil  
ObjectSpace.each\_object(Object) { |o|  
found = o if o.fname == fname  
}  
found  
end

end #Class Storable

# Storage.rb - datastore-module

# - Storage abstraction 1st. Scalability 2nd.

# - gold spike: store marshaled objects

# - future store YML -objects in a namespace of some kind.

# - future SQL

#Roadmap

# DB/QL support

# I. Marshall objects

# - serialize/re-instance

# - namespace?

# II. Yaml/JSON/XML

# III. ODB?

# IV. MySQL and so on

# 

#Inteface Roadmap

# \* Make a module instead of inheritable?!?

# \* store.config. Configurable parameters.

# \* Store object.

# \* Retrieve object.

# \* Sort/Compare/etc

require “singleton.rb”

class Storage

include Singleton

#Instantiated with:  
#Storage = Storage.instance

# 

#Requires:  
#writable storage\_home\_local\_path -directory  
#Object to be stored is of class storable

# 

#Usage:  
#Storage.store(object, path\_str)

# 

#Returns:  
#future: status code indicating the result

#TODO move this to config-file

@@storage\_home\_local\_path = ‘/tmp/’

attr\_reader :storage\_home\_local\_path

### Constructor

def initialize()

end #init

def set\_storage\_configuration()  
end

### CLASS METHODS

def self.store(relative\_path\_str, content\_string)  
store\_content\_string(relative\_path\_str, content\_string)  
end

def self.store\_content\_string(relative\_path\_str, content\_string)  
target\_path = @@storage\_home\_local\_path + relative\_path\_str  
#print target\_path  
wf\_io = File.open(target\_path, “w”)  
wf\_io.write(content\_string)  
unless wf\_io.closed?  
#wf\_io.flush()  
wf\_io.close()  
end  
end

def self.query(selector\_str, keyword\_str)

```
case selector_str
  when "by_path"
    items = Dir[@@storage_home_local_path + keyword_str]
    labels = Dir[@@storage_home_local_path + keyword_str + ".label"]
    items = items-labels

  when "by_class"
    #etc etc

end #case

```

end

def self.unpack(relative\_path\_or\_filename\_str)  
#returns unpacked stored object  
#resolve path  
relative\_path\_or\_filename\_str = relative\_path\_or\_filename\_str.gsub  
(@@storage\_home\_local\_path, “”) #remove path in case exists so no dbl  
path  
target\_path = @@storage\_home\_local\_path +  
relative\_path\_or\_filename\_str.to\_s

```
begin
  open(target_path) do |f|
  @loaded_object = Marshal.load(f)
  end
rescue StandardError => crash
  print "Storage unpack: Standard Error opening file "
  print target_path.to_s + ", returned: " + crash + ". "
end

return @loaded_object

```

end

end #e Storage

#Example code

Storage.instance #a instance of the Storage

class Tester \< Storable  
def initialize(some\_str)  
super()  
@stuff = Array.new  
20.times { @stuff.push(some\_str.to\_s) }  
end

attr\_reader :stuff  
end

this\_test = Tester.new(“Test for comp.lang.ruby”)  
this\_test.put\_into\_storage()  
print this\_test = “blah”

presumed\_obj = Dir[“/tmp/ **unknown\_object** ”][0].to\_s  
unserred = Storage.unpack(presumed\_obj)  
print unserred.inspect()  
print unserred.stuff #??!??

#end END END

Casimir P. - Portfolio [http://csmr.dreamhosters.com](http://csmr.dreamhosters.com)

---

<div class="post-metadata">

**Author:** ![Casimir\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/839c29/32.png) [@Casimir\_P](https://www.ruby-forum.com/u/Casimir_P)\
**Post date:** [December 16, 2008, 8:22pm UTC](https://www.ruby-forum.com/t/persistent-objects-with-ruby-simple-beginning/226032/2 "2008-12-16T20:22:16Z")

</div>

Casimir P. wrote:

> Object persistence, I want it, without SQL or other schemes that could be  
> implemented in ruby and somewhat automated instead. Smalltalk and Squeak  
> inspired. Objects exist, no CRUD or ‘saving’ or ‘writes’.
> 
> So, as an attempt to I made this Storage singleton and Storable -class.  
> (code at end or at [http://pastie.org/340631](http://pastie.org/340631) )

It might be interesting to compare your ideas with fsdb[1]. It does have  
metadata for objects, but the only meta attr currently used is file  
version.

[1] [FSDB](http://redshift.sourceforge.net/fsdb/doc/api/index.html)

---

<div class="post-metadata">

**Author:** ![Casimir\_P](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/839c29/32.png) [@Casimir\_P](https://www.ruby-forum.com/u/Casimir_P)\
**Post date:** [December 16, 2008, 10:32pm UTC](https://www.ruby-forum.com/t/persistent-objects-with-ruby-simple-beginning/226032/3 "2008-12-16T22:32:19Z")

</div>

Casimir P. wrote:

> Object persistence, I want it, without SQL or other schemes that could  
> be  
> implemented in ruby and somewhat automated instead. Smalltalk and Squeak  
> inspired. Objects exist, no CRUD or ‘saving’ or ‘writes’.

Have you looked at Madeleine?
