[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

how to add YAML serialization support to a class?

Luca Pireddu

6/26/2005 3:55:00 AM

Hello. Can someone point me to some documentation describing how to add YAML
support to a class? I have a class that contains an RGL graph. I'd like to
be able to save it and restore it, but

YAML::dump(RGL::DirectedAdjacencyGraph.new)

throws an exception

TypeError: can't dump anonymous class Class
from /usr//lib/ruby/1.8/yaml/rubytypes.rb:9:in `to_yaml'
from /usr//lib/ruby/1.8/yaml/baseemitter.rb:181:in `map'
from /usr//lib/ruby/1.8/yaml/baseemitter.rb:170:in `each'
from /usr//lib/ruby/1.8/yaml/baseemitter.rb:170:in `map'
from /usr//lib/ruby/1.8/yaml/rubytypes.rb:25:in `to_yaml'
from /usr//lib/ruby/1.8/yaml/rubytypes.rb:24:in `call'
from /usr//lib/ruby/1.8/yaml.rb:373:in `quick_emit'
from /usr//lib/ruby/1.8/yaml/rubytypes.rb:24:in `to_yaml'
from /usr//lib/ruby/1.8/yaml.rb:103:in `dump'

TIA.

Luca
2 Answers

Joel VanderWerf

6/26/2005 4:08:00 AM

0

Luca Pireddu wrote:
> Hello. Can someone point me to some documentation describing how to add YAML
> support to a class? I have a class that contains an RGL graph. I'd like to
> be able to save it and restore it, but
>
> YAML::dump(RGL::DirectedAdjacencyGraph.new)
>
> throws an exception
>
> TypeError: can't dump anonymous class Class

Looks like the problem is that somewhere in the graph of objects
connected to your instance is a Class object:

$ irb -r yaml
irb(main):001:0> YAML.dump(Class)
TypeError: can't dump anonymous class Class
...

(I don't see what's anonymous about Class...)

Anyway, there's nothing shameful about wanting to yaml a class! It's
easy to convince YAML to let you do it:

require 'yaml'

class Module
def is_complex_yaml?
false
end
def to_yaml( opts = {} )
YAML::quick_emit( nil, opts ) { |out|
out << "!ruby/module "
self.name.to_yaml( :Emitter => out )
}
end
end
YAML.add_ruby_type(/^module/) do |type, val|
subtype, subclass = YAML.read_type_class(type, Module)
val.split(/::/).inject(Object) { |p, n| p.const_get(n)}
end

class Class
def to_yaml( opts = {} )
YAML::quick_emit( nil, opts ) { |out|
out << "!ruby/class "
self.name.to_yaml( :Emitter => out )
}
end
end
YAML.add_ruby_type(/^class/) do |type, val|
subtype, subclass = YAML.read_type_class(type, Class)
val.split(/::/).inject(Object) { |p, n| p.const_get(n)}
end

p YAML.dump(Class) # ==> "--- !ruby/class Class"


So, really, all that is getting written is a reference to the class. Any
state in the class itself (class vars, class instance vars) is not stored.


Luca Pireddu

6/27/2005 11:12:00 PM

0

Joel VanderWerf wrote:

> Luca Pireddu wrote:
>> Hello. Can someone point me to some documentation describing how to add
>> YAML
>> support to a class? I have a class that contains an RGL graph. I'd like
>> to be able to save it and restore it, but
>>
>> YAML::dump(RGL::DirectedAdjacencyGraph.new)
>>
>> throws an exception
>>
>> TypeError: can't dump anonymous class Class
>
> Looks like the problem is that somewhere in the graph of objects
> connected to your instance is a Class object:
>
> $ irb -r yaml
> irb(main):001:0> YAML.dump(Class)
> TypeError: can't dump anonymous class Class
> ..
>
> (I don't see what's anonymous about Class...)
>
> Anyway, there's nothing shameful about wanting to yaml a class! It's
> easy to convince YAML to let you do it:
>
> require 'yaml'
>
> class Module
> def is_complex_yaml?
> false
> end
> def to_yaml( opts = {} )
> YAML::quick_emit( nil, opts ) { |out|
> out << "!ruby/module "
> self.name.to_yaml( :Emitter => out )
> }
> end
> end
> YAML.add_ruby_type(/^module/) do |type, val|
> subtype, subclass = YAML.read_type_class(type, Module)
> val.split(/::/).inject(Object) { |p, n| p.const_get(n)}
> end
>
> class Class
> def to_yaml( opts = {} )
> YAML::quick_emit( nil, opts ) { |out|
> out << "!ruby/class "
> self.name.to_yaml( :Emitter => out )
> }
> end
> end
> YAML.add_ruby_type(/^class/) do |type, val|
> subtype, subclass = YAML.read_type_class(type, Class)
> val.split(/::/).inject(Object) { |p, n| p.const_get(n)}
> end
>
> p YAML.dump(Class) # ==> "--- !ruby/class Class"
>
>
> So, really, all that is getting written is a reference to the class. Any
> state in the class itself (class vars, class instance vars) is not stored.

Thanks for your reply Joel. I think I understand the basic idea. To emit,
define a method #to_yaml in your class. To enable YAML to load your class
register the type with YAML using one of the add_x_type methods, and
associate a block that knows how to recreate your data structure from the
YAML parse tree.

For anyone who may be interested, I've found helpful documentation at this
site:
http://yaml4r.sourceforg...

Luca