ruby - How do I deserialize YAML documents from external sources and have full access on class members? -


in ruby object can transferred, i.e. serialized, yaml document saving output of "to_yaml" method file. afterwards, yaml file can read again, i.e. deserialized, using yaml::load method. moreover, 1 has full access on members of underlying class/object.

all of valid long i'm using ruby single platform. once serialize objects in java , deserialize them under ruby, cannot access object more because of nomethoderror exception. due to way objects/local data types named under different systems.

given ruby class "car":

# simple class describing car # class car   attr :brand, :horsepower, :color, :extra_equipment    def initialize(brand, horsepower, color, extra_equipment)     @brand = brand     @horsepower = horsepower     @color = color     @extra_equipment = extra_equipment   end   end 

creating simple instance:

# creating new instance of class 'car' ... porsche = car.new("porsche", 180, "red", ["sun roof", "air conditioning"]) 

calling porsche.to_yaml results in following output:

--- !ruby/object:car  brand: porsche color: red extra_equipment:  - sun roof - air conditioning horsepower: 180 

i test deserialization loading yaml output:

# reading existing yaml file file system sample_car = yaml::load(file.open("sample.yaml")) puts sample_car.brand # returns "porsche" 

this works expected, let's assume yaml document produced different system , lacks reference ruby, although having yaml-conform object description, "!car", instead of "!ruby/object:car":

--- !car  brand: porsche color: red extra_equipment:  - sun roof - air conditioning horsepower: 180 

this code:

# reading existing yaml file file system sample_car = yaml::load(file.open("sample.yaml")) puts sample_car.brand # returns "porsche" 

returns exception:

/path/yaml_to_object_converter.rb.rb:27:in `<main>': undefined method `brand' #<yaml::domaintype:0x9752bec> (nomethoderror) 

is there way deal objects defined in "external" yaml documents?

for me sample_car in irb shell evaluates to:

=> #<syck::domaintype:0x234df80 @domain="yaml.org,2002", @type_id="car", @value={"brand"=>"porsche", "color"=>"red", "extra_equipment"=>["sun roof", "air conditioning"], "horsepower"=>180}> 

then issued sample_car.value:

=> {"brand"=>"porsche", "color"=>"red", "extra_equipment"=>["sun roof", "air conditioning"], "horsepower"=>180} 

which hash. means, can construct your car object adding class method car so:

def self.from_hash(h)   car.new(h["brand"], h["horsepower"], h["color"], h["extra_equipment"]) end 

then tried it:

porsche_clone = car.from_hash(sample_car.value) 

which returned:

=> #<car:0x236eef0 @brand="porsche", @horsepower=180, @color="red", @extra_equipment=["sun roof", "air conditioning"]> 

that's ugliest way of doing it. there might others. =)

edit (19-may-2011): btw, figured lot easier way:

def from_hash(o,h)   h.each { |k,v|     o.send((k+"=").to_sym, v)   }   o end 

for work in case, constructor must not require parameters. can do:

foreign_car = from_hash(car.new, yaml::load(file.open("foreign_car.yaml")).value) puts foreign_car.inspect 

...which gives you:

#<car:0x2394b70 @brand="porsche", @color="red", @extra_equipment=["sun roof", "air conditioning"], @horsepower=180> 

Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -