<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: ini code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Sat, 11 Oct 2008 13:56:45 GMT</pubDate>
    <description>DZone Snippets: ini code</description>
    <item>
      <title>Ini file parser and writer</title>
      <link>http://snippets.dzone.com/posts/show/4918</link>
      <description>This file provides a read-wite handling for ini files. The data of a ini file is represented by a object which is populated with strings.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#&lt;br /&gt;# ini.rb - read and write ini files&lt;br /&gt;#&lt;br /&gt;# Copyright (C) 2007 Jeena Paradies&lt;br /&gt;# License: GPL&lt;br /&gt;# Author: Jeena Paradies (info@jeenaparadies.net)&lt;br /&gt;#&lt;br /&gt;# == Overview&lt;br /&gt;#&lt;br /&gt;# This file provides a read-wite handling for ini files.&lt;br /&gt;# The data of a ini file is represented by a object which&lt;br /&gt;# is populated with strings.&lt;br /&gt;&lt;br /&gt;class Ini&lt;br /&gt;  &lt;br /&gt;  # Class with methods to read from and write into ini files.&lt;br /&gt;  #&lt;br /&gt;  # A ini file is a text file in a specific format,&lt;br /&gt;  # it may include several fields which are sparated by&lt;br /&gt;  # field headlines which are enclosured by "[]".&lt;br /&gt;  # Each field may include several key-value pairs.&lt;br /&gt;  #&lt;br /&gt;  # Each key-value pair is represented by one line and&lt;br /&gt;  # the value is sparated from the key by a "=".&lt;br /&gt;  #&lt;br /&gt;  # == Examples&lt;br /&gt;  #&lt;br /&gt;  # === Example ini file&lt;br /&gt;  #&lt;br /&gt;  #   # this is the first comment which will be saved in the comment attribute&lt;br /&gt;  #   mail=info@example.com&lt;br /&gt;  #   domain=example.com # this is a comment which will not be saved&lt;br /&gt;  #   [database]&lt;br /&gt;  #   db=example&lt;br /&gt;  #   user=john&lt;br /&gt;  #   passwd=very-secure&lt;br /&gt;  #   host=localhost&lt;br /&gt;  #   # this is another comment&lt;br /&gt;  #   [filepaths]&lt;br /&gt;  #   tmp=/tmp/example&lt;br /&gt;  #   lib=/home/john/projects/example/lib&lt;br /&gt;  #   htdocs=/home/john/projects/example/htdocs&lt;br /&gt;  #   [ texts ]&lt;br /&gt;  #   wellcome=Wellcome on my new website!&lt;br /&gt;  #   Website description = This is only a example. # and another comment&lt;br /&gt;  #&lt;br /&gt;  # === Example object&lt;br /&gt;  #&lt;br /&gt;  #   A Ini#comment stores:&lt;br /&gt;  #   "this is the first comment which will be saved in the comment attribute"&lt;br /&gt;  #&lt;br /&gt;  #   A Ini object stores:&lt;br /&gt;  #&lt;br /&gt;  #   {&lt;br /&gt;  #    "mail" =&gt; "info@example.com",&lt;br /&gt;  #    "domain" =&gt; "example.com",&lt;br /&gt;  #    "database" =&gt; {&lt;br /&gt;  #     "db" =&gt; "example",&lt;br /&gt;  #     "user" =&gt; "john",&lt;br /&gt;  #     "passwd" =&gt; "very-secure",&lt;br /&gt;  #     "host" =&gt; "localhost"&lt;br /&gt;  #    },&lt;br /&gt;  #    "filepaths" =&gt; {&lt;br /&gt;  #     "tmp" =&gt; "/tmp/example",&lt;br /&gt;  #     "lib" =&gt; "/home/john/projects/example/lib",&lt;br /&gt;  #     "htdocs" =&gt; "/home/john/projects/example/htdocs"&lt;br /&gt;  #    }&lt;br /&gt;  #    "texts" =&gt; {&lt;br /&gt;  #     "wellcome" =&gt; "Wellcome on my new website!",&lt;br /&gt;  #     "Website description" =&gt; "This is only a example."&lt;br /&gt;  #    }&lt;br /&gt;  #   }&lt;br /&gt;  #&lt;br /&gt;  # As you can see this module gets rid of all comments, linebreaks&lt;br /&gt;  # and unnecessary spaces at the beginning and the end of each&lt;br /&gt;  # field headline, key or value.&lt;br /&gt;  #&lt;br /&gt;  # === Using the object&lt;br /&gt;  #&lt;br /&gt;  # Using the object is stright forward:&lt;br /&gt;  #&lt;br /&gt;  #   ini = Ini.new("path/settings.ini")&lt;br /&gt;  #   ini["mail"] = "info@example.com"&lt;br /&gt;  #   ini["filepaths"] = { "tmp" =&gt; "/tmp/example" }&lt;br /&gt;  #   ini.comment = "This is\na comment"&lt;br /&gt;  #   puts ini["filepaths"]["tmp"]&lt;br /&gt;  #   # =&gt; /tmp/example&lt;br /&gt;  #   ini.write()&lt;br /&gt;  # &lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # :inihash is a hash which holds all ini data&lt;br /&gt;  # :comment is a string which holds the comments on the top of the file&lt;br /&gt;  #&lt;br /&gt;  attr_accessor :inihash, :comment&lt;br /&gt;&lt;br /&gt;  #&lt;br /&gt;  # Creating a new Ini object&lt;br /&gt;  #&lt;br /&gt;  # +path+ is a path to the ini file&lt;br /&gt;  # +load+ if nil restores the data if possible&lt;br /&gt;  #        if true restores the data, if not possible raises an error&lt;br /&gt;  #        if false does not resotre the data&lt;br /&gt;  #&lt;br /&gt;  def initialize(path, load=nil)&lt;br /&gt;    @path = path&lt;br /&gt;    @inihash = {}&lt;br /&gt;    &lt;br /&gt;    if load or ( load.nil? and FileTest.readable_real? @path )&lt;br /&gt;      restore()&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Retrive the ini data for the key +key+&lt;br /&gt;  #&lt;br /&gt;  def [](key)&lt;br /&gt;    @inihash[key]&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Set the ini data for the key +key+&lt;br /&gt;  #&lt;br /&gt;  def []=(key, value)&lt;br /&gt;    raise TypeError, "String expected" unless key.is_a? String&lt;br /&gt;    raise TypeError, "String or Hash expected" unless value.is_a? String or value.is_a? Hash&lt;br /&gt;    &lt;br /&gt;    @inihash[key] = value&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Restores the data from file into the object&lt;br /&gt;  #&lt;br /&gt;  def restore()&lt;br /&gt;    @inihash = Ini.read_from_file(@path)&lt;br /&gt;    @comment = Ini.read_comment_from_file(@path)&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Store data from the object in the file&lt;br /&gt;  #&lt;br /&gt;  def update()&lt;br /&gt;    Ini.write_to_file(@path, @inihash, @comment)&lt;br /&gt;  end&lt;br /&gt;&lt;br /&gt;  #&lt;br /&gt;  # Reading data from file&lt;br /&gt;  #&lt;br /&gt;  # +path+ is a path to the ini file&lt;br /&gt;  #&lt;br /&gt;  # returns a hash which represents the data from the file&lt;br /&gt;  #&lt;br /&gt;  def Ini.read_from_file(path)&lt;br /&gt;        &lt;br /&gt;    inihash = {}&lt;br /&gt;    headline = nil&lt;br /&gt;    &lt;br /&gt;    IO.foreach(path) do |line|&lt;br /&gt;&lt;br /&gt;      line = line.strip.split(/#/)[0]&lt;br /&gt;      &lt;br /&gt;      # read it only if the line doesn't begin with a "=" and is long enough&lt;br /&gt;      unless line.length &lt; 2 and line[0,1] == "="&lt;br /&gt;        &lt;br /&gt;        # it's a headline if the line begins with a "[" and ends with a "]"&lt;br /&gt;        if line[0,1] == "[" and line[line.length - 1, line.length] == "]"&lt;br /&gt;          &lt;br /&gt;          # get rid of the [] and unnecessary spaces&lt;br /&gt;          headline = line[1, line.length - 2 ].strip&lt;br /&gt;          inihash[headline] = {}&lt;br /&gt;        else&lt;br /&gt;        &lt;br /&gt;          key, value = line.split(/=/, 2)&lt;br /&gt;          &lt;br /&gt;          key = key.strip unless key.nil?&lt;br /&gt;          value = value.strip unless value.nil?&lt;br /&gt;          &lt;br /&gt;          unless headline.nil?&lt;br /&gt;            inihash[headline][key] = value&lt;br /&gt;          else&lt;br /&gt;            inihash[key] = value unless key.nil?&lt;br /&gt;          end&lt;br /&gt;        end        &lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    inihash&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Reading comments from file&lt;br /&gt;  #&lt;br /&gt;  # +path+ is a path to the ini file&lt;br /&gt;  #&lt;br /&gt;  # Returns a string with comments from the beginning of the&lt;br /&gt;  # ini file.&lt;br /&gt;  #&lt;br /&gt;  def Ini.read_comment_from_file(path)&lt;br /&gt;    comment = ""&lt;br /&gt;    &lt;br /&gt;    IO.foreach(path) do |line|&lt;br /&gt;      line.strip!&lt;br /&gt;      break unless line[0,1] == "#" or line == ""&lt;br /&gt;      &lt;br /&gt;      comment &lt;&lt; "#{line[1, line.length ].strip}\n"&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    comment&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Writing a ini hash into a file&lt;br /&gt;  #&lt;br /&gt;  # +path+ is a path to the ini file&lt;br /&gt;  # +inihash+ is a hash representing the ini File. Default is a empty hash.&lt;br /&gt;  # +comment+ is a string with comments which appear on the&lt;br /&gt;  #           top of the file. Each line will get a "#" before.&lt;br /&gt;  #           Default is no comment.&lt;br /&gt;  #&lt;br /&gt;  def Ini.write_to_file(path, inihash={}, comment=nil)&lt;br /&gt;    raise TypeError, "String expected" unless comment.is_a? String or comment.nil?&lt;br /&gt;    &lt;br /&gt;    raise TypeError, "Hash expected" unless inihash.is_a? Hash&lt;br /&gt;    File.open(path, "w") { |file|&lt;br /&gt;      &lt;br /&gt;      unless comment.nil?&lt;br /&gt;        comment.each do |line|&lt;br /&gt;          file &lt;&lt; "# #{line}"&lt;br /&gt;        end&lt;br /&gt;      end&lt;br /&gt;      &lt;br /&gt;      file &lt;&lt; Ini.to_s(inihash)&lt;br /&gt;    }&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;  #&lt;br /&gt;  # Turn a hash (up to 2 levels deepness) into a ini string&lt;br /&gt;  #&lt;br /&gt;  # +inihash+ is a hash representing the ini File. Default is a empty hash.&lt;br /&gt;  #&lt;br /&gt;  # Returns a string in the ini file format.&lt;br /&gt;  #&lt;br /&gt;  def Ini.to_s(inihash={})&lt;br /&gt;    str = ""&lt;br /&gt;    &lt;br /&gt;    inihash.each do |key, value|&lt;br /&gt;&lt;br /&gt;      if value.is_a? Hash&lt;br /&gt;        str &lt;&lt; "[#{key.to_s}]\n"&lt;br /&gt;        &lt;br /&gt;        value.each do |under_key, under_value|&lt;br /&gt;          str &lt;&lt; "#{under_key.to_s}=#{under_value.to_s unless under_value.nil?}\n"&lt;br /&gt;        end&lt;br /&gt;&lt;br /&gt;      else&lt;br /&gt;        str &lt;&lt; "#{key.to_s}=#{value.to_s unless value2.nil?}\n"&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;    &lt;br /&gt;    str&lt;br /&gt;  end&lt;br /&gt;  &lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 23 Dec 2007 18:46:31 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4918</guid>
      <author>Jeena (Jeena Paradies)</author>
    </item>
    <item>
      <title>simple backup PHP application (php files + mysql db)</title>
      <link>http://snippets.dzone.com/posts/show/4539</link>
      <description>// backup a folder contains all .php files and it's mysql database. a backup.ini file is required for storing mysql root login and what folder to be backed up.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/bin/sh&lt;br /&gt;&lt;br /&gt;########################################&lt;br /&gt;# simple sctipt for daily / hourly backup of PHP app + Mysql DB&lt;br /&gt;# Copyleft (c) Sayid Munawar. chenull@yahoo.com&lt;br /&gt;# LICENSE: anyone can copy / modify / distribute. whatever lah&lt;br /&gt;#&lt;br /&gt;# example of workhours backup (8 am - 5 pm. Mon - Fri)&lt;br /&gt;# 0 8-17 * * 1-5 /home/backup/backup.sh&lt;br /&gt;#&lt;br /&gt;# example of simple dayly backup ( 6 pm. Mon - Fri)&lt;br /&gt;# 0 18 * * 1-5 /home/backup/backup.sh&lt;br /&gt;########################################&lt;br /&gt;&lt;br /&gt;########################################&lt;br /&gt;# example of backup.ini. REMOVE ALL leading '#'s&lt;br /&gt;# file must be chmod 600&lt;br /&gt;#[main]&lt;br /&gt;#target = /home/backup/storage&lt;br /&gt;#mysql_user = root   ; root can connect to any db&lt;br /&gt;#mysql_pass = secret ; mysql root password&lt;br /&gt;#&lt;br /&gt;#[hukum]&lt;br /&gt;#path = /home/hukum&lt;br /&gt;#mysql_db = hukum&lt;br /&gt;#&lt;br /&gt;#[phpmyadmin]&lt;br /&gt;#path = /home/phpmyadmin&lt;br /&gt;#mysql_db = test&lt;br /&gt;########################################&lt;br /&gt;&lt;br /&gt;PATH=$PATH:/usr/bin:/bin:/usr/local/bin&lt;br /&gt;&lt;br /&gt;inifile=`dirname $0`/backup.ini&lt;br /&gt;&lt;br /&gt;test ! -r $inifile &amp;&amp; echo "ERROR! backup.ini not found nor readable" &amp;&amp; exit 1&lt;br /&gt;&lt;br /&gt;#test apakah backup.ini bisa dibaca orang lain&lt;br /&gt;echo -n `stat -c '%a' $inifile` | grep -q '[0-7]00' &gt;/dev/null 2&gt;&amp;1&lt;br /&gt;test $? -gt 0 &amp;&amp; echo "ERROR! $inifile can be read by others" &amp;&amp; exit 2&lt;br /&gt;#test `stat -c '%U' $inifile` != 'root' &amp;&amp; echo "ERROR! $inifile ownernya bukan root" &amp;&amp; exit 3&lt;br /&gt;&lt;br /&gt;# function to parse ini file (backup.ini)&lt;br /&gt;#&lt;br /&gt;# $1 -&gt; file.ini&lt;br /&gt;# $2 -&gt; section&lt;br /&gt;_parse_ini () {&lt;br /&gt;    if [ -z "$1" ] || [ -z "$2" ]; then return 0; fi&lt;br /&gt;    eval `cat $1 | \&lt;br /&gt;       sed -e 's/[[:space:]]*\=[[:space:]]*/=/g' \&lt;br /&gt;           -e 's/;.*$//' \&lt;br /&gt;           -e 's/[[:space:]]*$//' \&lt;br /&gt;           -e 's/^[[:space:]]*//' \&lt;br /&gt;           -e "s/^\(.*\)=\([^\"']*\)$/\1=\"\2\"/" | \&lt;br /&gt;       sed -n -e "/^\[$2\]/,/^\s*\[/{/^[^;].*\=.*/p;}"`&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;_parse_ini $inifile main&lt;br /&gt;&lt;br /&gt;# coba konek &lt;br /&gt;mysql -u $mysql_user  -p${mysql_pass} -e '' &gt; /dev/null 2&gt;&amp;1&lt;br /&gt;test $? -gt 0 &amp;&amp; echo "ERROR! Failed to connect to mysql" &amp;&amp; exit 4&lt;br /&gt;&lt;br /&gt;# bikin target kalo blum ada&lt;br /&gt;test ! -d $target &amp;&amp; mkdir -p $target&lt;br /&gt;&lt;br /&gt;hari=`date +%A`&lt;br /&gt;jam=`date +%H`&lt;br /&gt;&lt;br /&gt;# get pwd&lt;br /&gt;cwd=`pwd`&lt;br /&gt;&lt;br /&gt;# looping&lt;br /&gt;for section in `cat $inifile | grep '^\[' | grep -v main | sed 's/\[//' | sed 's/\]//'`; do&lt;br /&gt;  outdir=$target/$section/$hari/$jam&lt;br /&gt;  echo Backing up ${section} to $outdir...&lt;br /&gt;  # parse .ini&lt;br /&gt;  _parse_ini $inifile $section&lt;br /&gt;  # cek dulu&lt;br /&gt;  test ! -d $path &amp;&amp; echo "Warning: $path not found.  Backup process of $section skipped" &amp;&amp; echo &amp;&amp; continue&lt;br /&gt;  mysql -u $mysql_user  -p${mysql_pass} -e '' $mysql_db &gt; /dev/null 2&gt;&amp;1&lt;br /&gt;  test $? -gt 0 &amp;&amp; echo "Warning: Database $mysql_db not found.  Backup process of $section skipped" &amp;&amp; echo &amp;&amp; continue&lt;br /&gt;&lt;br /&gt;  test ! -d $outdir &amp;&amp; mkdir -p $outdir&lt;br /&gt;  cd $path&lt;br /&gt;  tar -czpf $outdir/$section.tar.gz .&lt;br /&gt;  cd $cwd&lt;br /&gt;  mysqldump -Q -u $mysql_user -p${mysql_pass} $mysql_db | gzip &gt; $outdir/${mysql_db}.sql.gz&lt;br /&gt;  ln -fs $outdir/$section.tar.gz $target/$section/latest.tar.gz&lt;br /&gt;  ln -fs $outdir/${mysql_db}.sql.gz $target/$section/latest.sql.gz&lt;br /&gt;done&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 14 Sep 2007 00:15:12 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4539</guid>
      <author>chenull (Sayid Munawar)</author>
    </item>
    <item>
      <title>Parse Windows .ini Format with Ruby</title>
      <link>http://snippets.dzone.com/posts/show/563</link>
      <description>I didn't write this, I'm just posting it in case someone else finds it useful. I needed to parse a file that turned out to be windows .ini. gdsx in #ruby-lang came up with this for me. &lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;  #thanks to gdsx in #ruby-lang&lt;br /&gt;  def tame(input)&lt;br /&gt;          tamed = {}&lt;br /&gt;&lt;br /&gt;          # split data on city names, throwing out surrounding brackets&lt;br /&gt;          input = input.split(/\[([^\]]+)\]/)[1..-1]&lt;br /&gt;&lt;br /&gt;          # sort the data into key/value pairs&lt;br /&gt;          input.inject([]) {|tary, field|&lt;br /&gt;                  tary &lt;&lt; field&lt;br /&gt;                  if(tary.length == 2)&lt;br /&gt;                          # we have a key and value; put 'em to use&lt;br /&gt;                          tamed[tary[0]] = tary[1].sub(/^\s+/,'').sub(/\s+$/,'')&lt;br /&gt;                          # pass along a fresh temp-array&lt;br /&gt;                          tary.clear&lt;br /&gt;                  end&lt;br /&gt;                  tary&lt;br /&gt;                  }&lt;br /&gt;&lt;br /&gt;          tamed.dup.each { |tkey, tval|&lt;br /&gt;                  tvlist = tval.split(/[\r\n]+/)&lt;br /&gt;                  p tvlist&lt;br /&gt;                  tamed[tkey] = tvlist.inject({}) { |hash, val|&lt;br /&gt;                          k, v = val.split(/=/)&lt;br /&gt;                          hash[k]=v&lt;br /&gt;                          hash&lt;br /&gt;                          }&lt;br /&gt;                  }&lt;br /&gt;&lt;br /&gt;          tamed&lt;br /&gt;  end&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;here's what the input looks like&lt;br /&gt;&lt;code&gt;&lt;br /&gt;[Amsterdam]  &lt;br /&gt;Address=Amstelveenseweg 438;1084 JH;Amsterdam&lt;br /&gt;&lt;br /&gt;[Antwerp]  &lt;br /&gt;Address=Uitbreidingstraat 4;4-600;Antwerp&lt;br /&gt;&lt;br /&gt;[Austin]  &lt;br /&gt;Address=4221 South Harbor Expressway, Suite 400;Austin, Texas 78746&lt;br /&gt;&lt;br /&gt;[Baltimore / Smith]&lt;br /&gt;City=Baltimore &lt;br /&gt;Address=225 Johnson Avenue;Baltimore, Maryland 21209-3600&lt;br /&gt;&lt;br /&gt;[Baltimore / Calvert]&lt;br /&gt;City=Baltimore&lt;br /&gt;Address=151 South Belmont Street, Suite 2350;Baltimore, Maryland 21202-6832&lt;br /&gt;&lt;br /&gt;[Bangkok]&lt;br /&gt;Address=Unit 543, London Tower;495 North Sathorn Road, Yannawa, Sathorn Bangkok 45467&lt;br /&gt;Country=Thailand&lt;br /&gt;&lt;br /&gt;[Bergen]&lt;br /&gt;Country=Norway  &lt;br /&gt;City=Bergen&lt;br /&gt;Address=Torgallmenningen 4B;PO Box 2153 Sentrum, N-5811;Bergen&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;here's the output&lt;br /&gt;&lt;code&gt;&lt;br /&gt;{"Bergen"=&gt;{"City"=&gt;"Bergen", "Country"=&gt;"Norway", "Address"=&gt;"Torgallmenningen 4B;PO Box 2153 Sentrum, N-5811;Bergen"}, "Antwerp"=&gt;{"Address"=&gt;"Uitbreidingstraat 4;4-600;Antwerp"}, "Baltimore / Smith"=&gt;{"City"=&gt;"Baltimore", "Address"=&gt;"225 Johnson Avenue;Baltimore, Maryland 21209-3600"}, "Amsterdam"=&gt;{"Address"=&gt;"Amstelveenseweg 438;1084 JH;Amsterdam"}, "Bangkok"=&gt;{"Country"=&gt;"Thailand", "Address"=&gt;"Unit 543, London Tower;495 North Sathorn Road, Yannawa, Sathorn Bangkok 45467"}, "Austin"=&gt;{"Address"=&gt;"4221 South Harbor Expressway, Suite 400;Austin, Texas 78746"}, "Baltimore / Calvert"=&gt;{"City"=&gt;"Baltimore", "Address"=&gt;"151 South Belmont Street, Suite 2350;Baltimore, Maryland 21202-6832"}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Is this also an example of a state machine in Ruby?</description>
      <pubDate>Sun, 07 Aug 2005 09:21:03 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/563</guid>
      <author>d723 (Derek Gulbranson)</author>
    </item>
  </channel>
</rss>
