Jamming with Ruby YAML

When working with Ruby, the library/class I use and abuse most often is YAML. YAML stands for YAML Ain’t Markup Language and it is a versatile human friendly data serialization format. It is easier to use and understand than JSON.

A YAML file is much like a Java properties file in that is used to store name/value pairs. YAML is more powerful than simple Java properties file but that is a good way to think of it to begin with. Here is a example of a simple YAM file used to store user name and password.

user: juixe-username
pass: juixe-password

The above YAML snippet can go into a file, typically with a yml extension. To load the YAML file in ruby you can do it in with following Ruby code.

require 'yaml'

yml = YAML::load(File.open('userinfo.yml'))
puts yml['user'] # juixe-username

Just replace userinfo.yml with the name and path of your YAML file. The object that is loaded from the YAML file is a regular Ruby hash object so you can iterate through all the name/value pairs like the following.

require 'yaml'

yml = YAML.load_file 'userinfo.yml'
yml.each_pair { |key, value|
  puts "#{key} = #{value}"
}

What makes YAML files more powerful than a regular Java properties file is that you can complex object collections, structures, or hierarchies. For example, imagine that I want to log into a series of Twitter accounts and get their most recent at replies. I can keep a collection of twitter account usernames and passwords in a YAML file much like the following.

juixe:
 user: juixe-user
 pass: juixe-pass
techknow:
 user: techknow-user
 pass: techknow-pass

Here is the sample Ruby code that can be used to iterate through each user account from the YAML file.

require 'yaml'

yml = YAML.load_file 'userinfo.yml'
yml.each_key { |key|
  username = yml[key]['user']
  password = yml[key]['pass']

  puts "#{username} => #{password}"
  # login ...
}

You build more complex data structures than this using YAML, but this should be enough to get you going.

Related posts:

  1. Twitter Ruby Gem
  2. Download Twitter Profile Images Using Ruby
  3. ActiveRecord: Ruby on Rails Optional
  4. RubyConf: Rubinius – Hardcore Ruby
  5. Rails Single Table Inheritance
  6. Ruby On Flex


5 Responses to “Jamming with Ruby YAML”

  • janfri Says:

    Please replace require ‘rubygems’ with require ‘yaml’.

  • brainopia Says:

    There is a shortcut for YAML::load(File.open(‘userinfo.yml’)):
    YAML.load_file ‘userinfo.yml’

  • Thufir Says:

    Hmm, doesn’t quite work for me:

    thufir@ARRAKIS:~/projects/rss$ 
    thufir@ARRAKIS:~/projects/rss$ ruby user.rb 
    user.rb:6: undefined method `[]' for nil:NilClass (NoMethodError)
    	from user.rb:5:in `each_key'
    	from user.rb:5
    thufir@ARRAKIS:~/projects/rss$ 
    thufir@ARRAKIS:~/projects/rss$ nl user.rb
         1	require 'yaml'
           
         2	yml = YAML::load(File.open('user.yml'))
           
         3	yml.each_key { |key|
         4	  username = yml[key]['user']
         5	  password = yml[key]['pass']
           
         6	  puts "#{username} => #{password}"
         7	}
    thufir@ARRAKIS:~/projects/rss$ 
    thufir@ARRAKIS:~/projects/rss$ nl user.yml 
         1	juixe:
         2	user: juixe-user
         3	pass: juixe-pass
           
         4	techknow:
         5	user: techknow-user
         6	pass: techknow-pass
    thufir@ARRAKIS:~/projects/rss$ 
    

    Although, the earlier examples work fine, but the more complex yaml file doesn’t seem to get parsed correctly(?).

  • TechKnow Says:

    @Thufir – The problem that you have is because of the YAML file. Your YAML file does not define the nested structure in the example of this page. My example, define on root hash with two elements with keys ‘juixe’ and ‘techknow’, and the values of which was a nested hash. Your YAML file defines one hash with no nested values. Basically the nested structure comes from indentation. The space in front of ‘user’ and ‘pass’ are important to get the nested hash.

  • trans Says:

    > “It is easier to use and understand than JSON.”

    Probably more precise to say “It is more human oriented” or “ergonomic” or something like that. JSON is very easy to understand, it’s just not as easy to use b/c it is more machine-centric.

Leave a Reply