Friday, August 29, 2008

Marshaling the Ruby Way

This post is for the .NET developer who is looking at IronRuby but is otherwise unfamiliar with Ruby. As you learn Ruby, keep in mind a question that Ruby programmers like to ask themselves a lot, "What is the Ruby Way of solving this problem?" Today the problem is marshaling an object and we're going to solve it the Ruby Way.

If you're like most other .NET developers, you're probably thinking about BinaryFormatters or perhaps you prefer XmlSerializers. Maybe you're thinking about DeserializationCallbacks or XmlIgnoreAttributes and where to put them. Stop right there! That's definitely not the Ruby Way.

Let's define a Ruby class:
class Person
attr_reader :first_name, :last_name, :hobbies

def initialize(first_name, last_name, *hobbies)
@first_name = first_name
@last_name = last_name
@hobbies = hobbies
end
end

This is just a simple class with three read-only attributes: first_name, last_name, and hobbies. How would we create an instance of our class and marshal it the Ruby Way?
ray = Person.new("Ray", "Vernagus", "programming", "walking")
yml = ray.to_yaml
puts yml

to_yaml, what's that? YAML stands for "YAML ain't markup language." Did that make you smile? Now that's the Ruby Way! ;) YAML is very simple but also very powerful. It's the kind of notation that you would write yourself if you were just jotting a class down on a piece of paper except that it's structured and standardized. Here's what our marshaled person looks like:
--- !ruby/object:Person
first_name: Ray
hobbies:
- programming
- walking
last_name: Vernagus

Not bad, aye? That's about as ugly as you're likely to see YAML get. I encourage you to learn more about YAML and to use it in place of XML every chance that you get.

We can get our person back just as easily:
p = YAML.load(yml)
puts p.inspect

and this prints:
#<Person:0x0000064 @first_name="Ray", @hobbies=["programming", "walking"], @last_name="Vernagus">


This is all running in IronRuby (batteries-included version).

No comments: