From: Joel VanderWerf Date: 2006-02-04T05:11:19+09:00 Subject: [YAML] serializing Class and Module objects Hey, _why, what do you think about allowing YAML to dump/load Class and Module objects rather than gagging? I've posted code like the following (different versions for 1.8.2 and 1.8.4) several times in response to inquiries on ruby-talk, and found it useful myself. ===================================================== Test code: enum_y = [Enumerable, Comparable, String, File].to_yaml puts enum_y p YAML.load(enum_y) ===================================================== Test output: --- - !ruby/module Enumerable - !ruby/module Comparable - !ruby/class String - !ruby/class File [Enumerable, Comparable, String, File] ===================================================== require 'yaml' if defined?(YAML.type_tag) # old version of 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 else class Module yaml_as "tag:ruby.yaml.org,2002:module" def Module.yaml_new( klass, tag, val ) if String === val val.split(/::/).inject(Object) {|m, n| m.const_get(n)} else raise YAML::TypeError, "Invalid Module: " + val.inspect end end def to_yaml( opts = {} ) YAML::quick_emit( nil, opts ) { |out| out.scalar( "tag:ruby.yaml.org,2002:module", self.name, :plain ) } end end class Class yaml_as "tag:ruby.yaml.org,2002:class" def Class.yaml_new( klass, tag, val ) if String === val val.split(/::/).inject(Object) {|m, n| m.const_get(n)} else raise YAML::TypeError, "Invalid Class: " + val.inspect end end def to_yaml( opts = {} ) YAML::quick_emit( nil, opts ) { |out| out.scalar( "tag:ruby.yaml.org,2002:class", self.name, :plain ) } end end end -- vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407