<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>DevChix » Ruby</title>
	
	<link>http://www.devchix.com</link>
	<description>Boys can't have all the fun</description>
	<pubDate>Sat, 14 Jun 2008 06:48:23 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.5.1</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/devchix/QbOG" type="application/rss+xml" /><feedburner:browserFriendly></feedburner:browserFriendly><item>
		<title>Multiple object forms, delegation, and has_one…</title>
		<link>http://www.devchix.com/2008/06/03/multiple-object-forms-delegation-and-has_one/</link>
		<comments>http://www.devchix.com/2008/06/03/multiple-object-forms-delegation-and-has_one/#comments</comments>
		<pubDate>Wed, 04 Jun 2008 05:08:29 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=162</guid>
		<description><![CDATA[I had an ah ha moment that maybe shouldn&#8217;t have been such an ah ha moment but it was so I figured I would share it.  Yeah so I am sure most of us have  had a situation where we needed to have multiple model forms. Most of the time now days I [...]]]></description>
			<content:encoded><![CDATA[<p>I had an ah ha moment that maybe shouldn&#8217;t have been such an ah ha moment but it was so I figured I would share it.  Yeah so I am sure most of us have  had a situation where we needed to have multiple model forms. Most of the time now days I use attribute_fu to solve this issue but attribute_fu doesn&#8217;t work with has_one associations. Today I had a situation where I had two fields that were required for a has_one association object. Long story short it came to me that if we just used the delegate method provided by rails that we could essentially act like the attributes we were setting were on the parent model. This meant we only needed to create one form with multiple fields even though some of those fields were actually on a different model. I then remembered that back when I was working with the guys over at ThoughtWorks that we used a Ruby Extension called Forwardable to be able to delegate multiple attributes on one object.</p>
<p>So instead of this:<br />
<code><br />
delegate :first_name, :to => :profile<br />
delegate :last_name, :to => :profile<br />
delegate :some_other_attribute, :to => :profile<br />
</code></p>
<p>side note: I&#8217;m not sure but I don&#8217;t believe delegate can take multiple attributes (I tried to look this up but for some reason couldn&#8217;t find the documentation for this method and didn&#8217;t have time to dig in the code) </p>
<p>You could do the following:</p>
<p>include the Ruby Extension Forwardable in the parent model class</p>
<p><code><br />
include Forwardable<br />
</code></p>
<p>and then add this line:<br />
<code><br />
def_delegators  :profile, :first_name, :last_name, :some_other_attribute<br />
</code></p>
<p>So yeah that was my little ah ha moment. I am sure there are even better ways than this but this was better than what we were looking at doing to begin with.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/06/03/multiple-object-forms-delegation-and-has_one/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Conf 2008</title>
		<link>http://www.devchix.com/2008/05/30/rails-conf-2008/</link>
		<comments>http://www.devchix.com/2008/05/30/rails-conf-2008/#comments</comments>
		<pubDate>Fri, 30 May 2008 18:55:18 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<category><![CDATA[News]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=161</guid>
		<description><![CDATA[Hello Ladies,
I am reporting from RailsConf 2008. The main focus of this post is logistics for the conference. I&#8217;ll be posting about the talks as soon as I get to attend one. I have been running around trying to take care of DevChix related stuff.
We were unable to get an official room for a BoF [...]]]></description>
			<content:encoded><![CDATA[<p>Hello Ladies,<br />
I am reporting from RailsConf 2008. The main focus of this post is logistics for the conference. I&#8217;ll be posting about the talks as soon as I get to attend one. I have been running around trying to take care of DevChix related stuff.</p>
<p>We were unable to get an official room for a BoF but I have decided we will just take over some area of the convention center. Lets meet outside Exhibit Hall E at 7:30 on Saturday night. We can discuss whatever we want to. We are also planning appetizers and cocktails after the BoF. <a href="http://www.hashrocket.com">Hashrocket Inc</a>, the company I work for is sponsoring the evening. Thanks Hashrocket! </p>
<p>Please either come to the BoF for more information or find one of the ladies with a DevChix logo on their badges for more information.  I will also have stickers to give out (until they run out).</p>
<p>We would love to meet ALL the women developers at the conference so please come out and get to know us. </p>
<p>Cheers<br />
Desi</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/05/30/rails-conf-2008/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Book Review, “Pro Active Record”</title>
		<link>http://www.devchix.com/2008/03/12/book-review-pro-active-record/</link>
		<comments>http://www.devchix.com/2008/03/12/book-review-pro-active-record/#comments</comments>
		<pubDate>Thu, 13 Mar 2008 01:39:09 +0000</pubDate>
		<dc:creator>Nola</dc:creator>
		
		<category><![CDATA[Book]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/03/12/book-review-pro-active-record/</guid>
		<description><![CDATA[Published by Apress
By Kevin Marshall, Chad Pytel, Jon Yurek
Book Info
Sample Chapter: Ch. 01 - Introducing Active Record
Table of Contents 
Years ago when I was in PHP Land (now I travel quite a bit more! haha), I strugged for months with how to write a good ORM . It was tough, because I wanted to abstract [...]]]></description>
			<content:encoded><![CDATA[<p>Published by Apress<br />
By Kevin Marshall, Chad Pytel, Jon Yurek<br />
<a href="http://apress.com/book/view/9781590598474">Book Info</a><br />
<a href="http://apress.com/book/downloadfile/3712">Sample Chapter: Ch. 01 - Introducing Active Record</a><br />
<a href="http://apress.com/book/downloadfile/3711">Table of Contents</a> </p>
<p>Years ago when I was in PHP Land (now I travel quite a bit more! haha), I strugged for months with how to write a good ORM . It was tough, because I wanted to abstract the &#8220;boring logic&#8221; of retrieving records from a database without writing SQL but still remain flexible enough. I never really came up with a good model. I used the DAO from &#8220;extreme php&#8221; library which I think was a knock off from java. It was ok, but I still didn&#8217;t feel like I had &#8220;arrived&#8221;. </p>
<p>When I discovered Ruby on Rails, I found ActiveRecord. Ahh HA! Finally, this is what I was looking for. At first I thought it was part of Rails, but its not. Its a standalone library and you can use it with straight up ruby scripts. </p>
<p>I got a review copy of &#8220;Pro Active Record&#8221; some time ago and read it some when I got it, then some later, and now I am going to officially write up a review! </p>
<p>If you do anything with Active Record, get this book. The things that are briefly mentioned in most Rails books are described in detail in this book.<br />
<strong><br />
Chapter 1 -  Introducing Active Record</strong></p>
<p>Most of the time, the first chapters of a book are boring to me. I don&#8217;t need another &#8220;History of the Internet&#8221;  or how &#8220;HTML was developed&#8221; &#8230; blah blah. But this one, the story is only 1 page. And it actually has some introductory scripts on using Active Record, so you can see right away how it works. It also explains the benefits of MVC and why ORMs are good. Some people still don&#8217;t get it!</p>
<p><strong>Chapter 2 - Active Record and SQL</strong></p>
<p>This chapter helps you translate the &#8220;sql in your head&#8221; to how to write it with Active Record. I&#8217;ve used Active Record so much that now I have forgotten most of my SQL,   which is kind of embarrassing. :) I now find writing sql tedious and boring! I would have actually called this chapter &#8220;Demystifying Active Record&#8221; since it explains why all the dynamic finders work. You&#8217;ll also find transactions and locking explained here.</p>
<p><strong>Chapter 3 - Setting up Your Database</strong></p>
<p>Migrations! The Awesome Thing that can turn into a nightmare for large rails projects with multiple developers&#8230;. definitely have to decide on some best practices with your team on this one. The chapter has only one thing to say about this &#8212; assume any checked in migration has already been run by your team and the migration should not be edited and checked back in! You&#8217;ll have to make another migration file with your changes.</p>
<p><code>[tip]<br />
Nola&#8217;s Note: When you make a migration, test it both UP and DOWN!! Here&#8217;s what I do &#8212;<br />
write a migratiion<br />
rake db:migrate   (go up to the version with new code)<br />
rake db:migrate VERSION=n-1,  (go to version before the latest)<br />
rake db:migrate  (back to lastest)<br />
rake db:migrate VERSION=0  (back to blank db)<br />
rake db:migrate (back to latest)<br />
[/tip]</code></p>
<p>Just to be sure its all good &#8212; even on a new database!<br />
<strong><br />
Chapter 4 - Core Features of Active Record</strong></p>
<p>Now is the fun stuff - Callbacks. This is magic. This makes Active Record so flexible, and is one thing I could never figure out how to do with my PHP ORMs. I use call backs to set defaults for fields. If its just a straight default, then I set it in the database but if I need to make a decision, (if this field then this field..) then I can use it in a callback.</p>
<p>Associations - at first this is very confusing! I don&#8217;t know how many times I got &#8220;has_many&#8221; and &#8220;belongs_to&#8221; mixed around in the beginning. </p>
<p>Validations - Awesome. I had to do some ruby code without a database and I really really really missed the validations. It took me like 5x longer than it should! Understanding all of these validation methods will make your life so much more enjoyable. I really really hate doing boring, repetitive stuff&#8230;it seems so wasteful to me.<br />
<strong><br />
Chapter 5 - Bonus Features</strong></p>
<p>Everybody likes a bonus and this isn&#8217;t even the last chapter of the book. </p>
<p>Java people will like the Active Record Observers &#8212; seems a little AOP to me (aspect orienteted programming) and something I probably have neglected to use to their fullest extent. </p>
<p>Acting up &#8212; Learn how to &#8220;save time&#8221; with the &#8220;acts_as&#8221; magic:  List, Tree, Nested Sets.  If your data needs these structures, you got it made. I can imaging how much longer it would take to write this stuff in perl or php. </p>
<p>Composed of - I haven&#8217;t used this, but this looks like a good way to make sensible objects out of database tables. There is quite a bit of explanation and examples of this, it will come in handy.</p>
<p>There are a few other in depth explanations of things, such as method_missing which is how alot of the magic happens. Rock on.<br />
<strong><br />
Chapter 6 - Active Record Testing and Debugging<br />
</strong><br />
Ahh yes, Testing. My favorite subject. My friends who know how much I love testing say I am sick. I must have an inner need to PROVE I am right or something, haha. </p>
<p>The chapter goes into depth about using test_unit with Active Record, sadly  no RSpec. But, it does go into all the error messages that Active Record throws so you can write good try/catch blocks and make very exact error messages (probably best logged for the admin rather then displayed to the user!) <strong></p>
<p>Chapter 7 - Working with Legacy Schema</strong></p>
<p>Here&#8217;s how you work with that old database that just won&#8217;t die&#8230; or that management won&#8217;t let you totally redo. Active Record follows some of the principles of Rails &#8220;convention over configuration&#8221; &#8230; relying on table and column naming conventions to figure out how to build your object&#8230;.but still giving you a way out if you want your tables singular and your primary id field called &#8220;myawesomeid&#8221; instead of &#8220;id&#8221; </p>
<p> I&#8217;ve used some of these things on an older database and it was possible! Not too bad if thats what you have to work with.<br />
<code><br />
[soapbox]<br />
Some people find this annoying &#8220;oh gosh! my library can&#8217;t make decisions for me! OMG! That sucks&#8221; ..  to that I say, &#8220;Umm ok. But if you follow these conventions then I can come into your project and know exactly what is going on&#8221; &#8230; like with web standards, we all harp on how IE and FF do things differently, yet people want to bellyache about Active Record preferring to have plural names and id field called &#8220;id&#8221;.  Right. </p>
<p> Follow the dang convention and find something worth complaining about to complain about. :)<br />
[/soapbox]</code><br />
<strong><br />
Chapter 8 - Active Record and The Real World</strong></p>
<p>This chapter goes into depth about the library and encourages you to go read the Active Record code. Always a good idea to know what it is you are using :)  I&#8217;ve actually learned ruby better by reading source code. The chapter walks you through basic structure of the files. Very cool. </p>
<p><code>[soapbox]<br />
I used to work at a place that didn&#8217;t like any &#8220;outside code&#8221;  because they were afraid &#8220;OMG &#8230; it will send our passwords to Russia!&#8221; &#8230;  ok, well I am not an idiot. I read over any code that I use that I didn&#8217;t write. I look at the tests to see if I am using it right. I even RUN the tests so I can be sure its working as advertised.<br />
[/soapbox]</code></p>
<p>Alternatives to Active Record - with EXAMPLES! If something about Active Record doesn&#8217;t set too well with you, take a look at the alternatives. Sometimes I look at the alternatives and decide that the first wasn&#8217;t so bad after all. You&#8217;ll find examples of DBI, Og, ActiveRelation.</p>
<p>Finally a section on Q and A finishes up this book. The Appendix has a complete reference of ActiveRecord methods to make this book a well rounded reference, tips, documentation and very handy to have at your desk! </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/03/12/book-review-pro-active-record/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HAML Tip</title>
		<link>http://www.devchix.com/2008/01/28/haml-tip/</link>
		<comments>http://www.devchix.com/2008/01/28/haml-tip/#comments</comments>
		<pubDate>Mon, 28 Jan 2008 19:22:38 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/01/28/haml-tip/</guid>
		<description><![CDATA[So we were having an issue with haml and using a text-area output.  It had indentation when it should not have and double indented after doing a save. A quick google search brought me to Ray Morgan&#8217;s Blog for the answer. Basically instead of using the = sign use a ~ and it will [...]]]></description>
			<content:encoded><![CDATA[<p>So we were having an issue with haml and using a text-area output.  It had indentation when it should not have and double indented after doing a save. A quick google search brought me to <a href="http://raycmorgan.com/2007/10/10/quick-haml-tip-preserve-whitespace">Ray Morgan&#8217;s Blog</a> for the answer. Basically instead of using the = sign use a ~ and it will preserve whitespace. Thanks Ray. I am posting it here so I will remember where to find it if/when I forget what the answer was in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/01/28/haml-tip/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Call Me! A quick how-to for getting dialable phone numbers in your Rails app.</title>
		<link>http://www.devchix.com/2008/01/22/call-me-a-quick-how-to-for-getting-dialable-phone-numbers-in-your-rails-app/</link>
		<comments>http://www.devchix.com/2008/01/22/call-me-a-quick-how-to-for-getting-dialable-phone-numbers-in-your-rails-app/#comments</comments>
		<pubDate>Tue, 22 Jan 2008 17:08:11 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/01/22/call-me-a-quick-how-to-for-getting-dialable-phone-numbers-in-your-rails-app/</guid>
		<description><![CDATA[This might be something everyone knows but just in case I figured I would post a quick how-to on getting a clickable phone number in your Rails app. This example is only for the iPhone user_agent but you can make it work for other types as well as long as you know the user_agent.
Place the [...]]]></description>
			<content:encoded><![CDATA[<p>This might be something everyone knows but just in case I figured I would post a quick how-to on getting a clickable phone number in your Rails app. This example is only for the iPhone user_agent but you can make it work for other types as well as long as you know the user_agent.</p>
<p>Place the following code snippet in your application.rb file </p>
<pre><code> session :mobile => true, :if => proc { |request| Utility.mobile?(request.user_agent) }

  class Utility

    def self.mobile?(user_agent)
      user_agent =~/(iPhone)/i
    end
  end
</code></pre>
<p>Then in your view or your presenter code put a check for the session variable and if it is set then display the clickable phone number with the tel protocol in the href like so</p>
<pre><code>
"tel:#{contact.phone}"
</code></pre>
<p>and if its not set then just do things normally. Make sure you have the check there because if you don&#8217;t then when someone clicks the link in the browser it will complain about not understanding the tel protocol.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/01/22/call-me-a-quick-how-to-for-getting-dialable-phone-numbers-in-your-rails-app/feed/</wfw:commentRss>
		</item>
		<item>
		<title>A Hello World for Ruby on Ragel 6.0</title>
		<link>http://www.devchix.com/2008/01/13/a-hello-world-for-ruby-on-ragel-60/</link>
		<comments>http://www.devchix.com/2008/01/13/a-hello-world-for-ruby-on-ragel-60/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 13:22:11 +0000</pubDate>
		<dc:creator>Ana Nelson</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/01/13/a-hello-world-for-ruby-on-ragel-60/</guid>
		<description><![CDATA[This is an updated version of this tutorial. This updated version is compatible with Ruby 1.8 and Ruby 1.9, and Ragel 6.0.
By the end of this post, you&#8217;ll be able to turn a simple string &#8220;h&#8221; into the much longer and more interesting string &#8220;hello world!&#8221; using the magic of Ragel, all from the comfort [...]]]></description>
			<content:encoded><![CDATA[<p>This is an updated version of <a href="http://www.devchix.com/2007/12/13/a-hello-world-for-ruby-on-ragel/">this tutorial</a>. This updated version is compatible with Ruby 1.8 and Ruby 1.9, and Ragel 6.0.</p>
<p>By the end of this post, you&#8217;ll be able to turn a simple string &#8220;h&#8221; into the much longer and more interesting string &#8220;hello world!&#8221; using the magic of Ragel, all from the comfort of Ruby. Ragel is a very powerful state machine compiler and parser generator, which is at the heart of software like Mongrel and Hpricot. It&#8217;s able to generate C, C++, Objective-C, D, Java or Ruby code.</p>
<p>Ragel has excellent documentation provided by the author. My goal here is just to give you some context so that the documentation &#8220;sticks&#8221; when you read it, and to give you a working example which you can modify as you explore Ragel&#8217;s functionality. If you want to skip ahead, the full example is <a href="http://dev.agent.ie/svn/ragel/examples/simple_state_machine.rl">here</a>.</p>
<p>The first step, of course, is installing Ragel. The <a href="http://www.cs.queensu.ca/~thurston/ragel/">Ragel home page</a> has a Download section which lists ports for various platforms. If you already have Ragel installed, check that the version is 6.0 or higher. You can also compile and install Ragel from the source. Even if you don&#8217;t want to install from source it&#8217;s handy to have a copy of it to get some examples to play with. The subversion repository for Ragel is located here:</p>
<pre><code>svn://mambo.cs.queensu.ca/ragel/trunk/
</code></pre>
<p>As usual the test/ directory is your friend, also check out the examples/ directory. As per <a href="http://groups.google.com/group/ragel-users/browse_thread/thread/952c8cc75e6efef6">this thread</a>, try searching for &#8220;LANG: ruby&#8221;.</p>
<p>When writing Ragel code, you create a file with a .rl extension. The .rl file is written in the &#8220;host&#8221; language, in this case Ruby, and the Ragel machine specification is embedded within the Ruby code using special delimiters. There&#8217;s actually no obligation to specify a state machine, so a perfectly valid .rl file is:</p>
<pre><code>puts "hello world"
</code></pre>
<p>Don&#8217;t worry, I&#8217;m going to do a better Hello World than that, but this is a good place to start. To convert this .rl file into an executable .rb file, use the &#8220;ragel&#8221; command with a -R flag to indicate that you want Ruby code.</p>
<pre><code>ragel -R hello_world.rl
</code></pre>
<p>This will create a file entitled hello_world.rb with the following contents:</p>
<pre><code># line 1 "hello_world.rl"
puts "hello world"
</code></pre>
<p>I&#8217;ll, er, leave executing that file as an exercise for the diligent student.</p>
<p>Ragel actually does this conversion in 2 stages. First it creates an XML file, then converts the XML to Ruby. If you want to view this intermediate XML then you can pass the -x flag in addition to the -R flag.</p>
<pre><code>ragel -R -x simple_state_machine.rl > simple_state_machine.xml
</code></pre>
<p>Now, let&#8217;s write some actual Ragel. Start a new .rl file or <a href="http://dev.agent.ie/svn/ragel/examples/simple_state_machine.rl">download the example</a> and read along. We&#8217;re going to create a machine which prints &#8220;hello world!&#8221; when it&#8217;s passed the string &#8220;h&#8221;, and does nothing otherwise. To indicate to the ragel compiler that we are writing instructions for it, and not Ruby code, we need to place our Ragel code within double-percent-sign-curly-brackets %%{ and }%% , or you can enter a single line instruction by just typing %%. (See page 6 of the User Guide.) Here&#8217;s our state machine specification:</p>
<pre><code>%%{
  machine hello;
  expr = "h";
  main := expr @ { puts "hello world!" } ;
}%%
</code></pre>
<p>A quick overview of what&#8217;s happening here. The name of this machine is &#8220;hello&#8221; (Ragel makes us name it). It recognizes a single token, the string &#8220;h&#8221;. When it encounters that token, it performs (in Ruby) the action:</p>
<pre><code>puts "hello world"</code></pre>
<p>Now, if you were to run the ragel command on this file it would compile, but you would basically end up with a blank Ruby file. We have only specified the machine, we also have to tell Ragel to actually translate this machine into Ruby code using Ragel&#8217;s write statements. The first write statement we need to add is</p>
<pre><code>  %% write data;
</code></pre>
<p>If you add this line after the state machine definition block, it will compile, as long as you remember to add a blank line afterwards. (After you&#8217;ve worked with parsers for a while you come to appreciate newlines in a whole new way.) After adding this line and compiling, you should have a rather significant Ruby file with lots of class << self statements all generated by Ragel. You don't need to study this code, at least not right now. ItÃ¢â‚¬â„¢s pretty dull and ugly. And, if you run the ruby file at this point, you wonÃ¢â‚¬â„¢t see any output.</p>
<p>There are 2 more write statements to add, and for convenience we're going to place them within a ruby method. The argument to this method is going to be the string we want to parse. Ragel expects to find a variable named "data" containing an array of ASCII codes, so we will need to convert our string to an array. This is done very easily in Ruby using the unpack method.</p>
<pre><code>def run_machine(data)
  data = data.unpack("c*") if data.is_a?(String)
  %% write init;
  %% write exec;
end
</code></pre>
<p>write init tells Ragel that we want to generate initialization code for the state machine. The code Ragel generates here is:</p>
<pre><code>begin
  p ||= 0
  pe ||= data.length
  cs = hello_start
end
</code></pre>
<p>The variable p keeps track of which character in the data string we are currently parsing, starting at 0. pe is an upper limit for p. cs stores the current state of the state machine, and here it is initialized to the starting state of the state machine. These variables are discussed in the User Guide.</p>
<p>write exec tells Ragel to write the meat of the parser (finally!). The code generated here will actually take an input (the data argument) and determine what the state of the system should be based on that input, executing any actions which might be triggered along the way. Let&#8217;s add some puts statements so we can follow the code execution.</p>
<pre><code>def run_machine(data)
  data = data.unpack("c*") if data.is_a?(String)
  puts "Running the state machine with input #{data}..."

  %% write init;
  %% write exec;

  puts "Finished. The state of the machine is: #{cs}"
  puts "p: #{p} pe: #{pe}"
end
</code></pre>
<p>Just add 2 more lines at the end to call run_machine with various arguments and then we can actually compile and run our state machine.</p>
<pre><code>run_machine "h"
run_machine "x"
</code></pre>
<p>And here we go&#8230;</p>
<pre><code>Running the state machine with input 104...
hello world!
Finished. The state of the machine is: 2
p: 1 pe: 1
Running the state machine with input 120...
Finished. The state of the machine is: 0
p: 0 pe: 1
</code></pre>
<p>It worked! Now, to help us interpret the values of p, pe and cs let&#8217;s take a look at the state chart of this state machine. Ragel has built-in Graphviz support to create state charts. We need to use the -V flag instead of -R.</p>
<pre><code>ragel -V simple_state_machine.rl > simple_state_machine.dot
</code></pre>
<p>If you render the resulting simple_state_machine.dot file in <a href="http://www.graphviz.org/">Graphviz</a>, you should get something like this:</p>
<p><img id="image114" src="http://www.devchix.com/wp-content/uploads/2007/12/simple_state_machine.png" alt="State Chart for Simple State Machine" /></p>
<p>We can see that the state machine has only one possible transition, from state 1 to state 2. When we passed &#8220;h&#8221; as the parameter to run_machine we did indeed end up with the variable cs (current state) equal to 2 at the end of our run. When &#8220;x&#8221; was passed, we ended up with cs = 0. 0 is the error state, indicating that an error occurred in the state machine. (You can tell that 0 is the error state by reading some of the variable assignments generated by write data, the code I said was dull and ugly.)</p>
<p>In the label 104/4:18 over the arrow transitioning from state 1 to state 2, the 104 corresponds to the ASCII code for the letter &#8220;h&#8221;. (Type &#8220;?h&#8221; in irb.) The / indicates that an action is being performed, and 4:18 tells us that the action starts at line 4, column 18 of the .rl file. Had we given our action a name, that would have appeared here instead of the file position.</p>
<p>By the way, here&#8217;s the (textmate-specific) shell script I use to run all these steps quickly:</p>
<pre><code>ragel -R simple_state_machine.rl
ragel -V simple_state_machine.rl > simple_state_machine.dot
dot -Tpng simple_state_machine.dot > simple_state_machine.png
open simple_state_machine.png
ruby simple_state_machine.rb
mate simple_state_machine.out
</code></pre>
<p>Now, try running this code:</p>
<pre><code>  run_machine "hh"
</code></pre>
<p>You should get:</p>
<pre><code>Running the state machine with input 104104...
hello world!
Finished. The state of the machine is: 0
p: 1 pe: 2
</code></pre>
<p>You don&#8217;t get &#8220;hello world!&#8221; twice. Sorry. Our state machine is only looking at a the first character we pass. It knows we gave it two characters, the variable pe = 2, but after it evaluates the first character it&#8217;s in a final state. There&#8217;s no arrow coming out of the state 2 circle. So, passing additional input results in the system entering the error state. If we want the entire data string to be evaluated, we need to make a small change to our machine specification.</p>
<pre><code>main := expr+ @ { puts "hello world!" } ;
</code></pre>
<p><img id="image116" src="http://www.devchix.com/wp-content/uploads/2007/12/never_ending_simple_state_machine.png" alt="Endless Simple State Machine" /></p>
<p>(Try expr* instead of expr+ and see how the state chart is different.)</p>
<p>Now, try running this new state machine with inputs &#8220;hhh&#8221; and &#8220;hxh&#8221;:</p>
<pre><code>Running the state machine with input 104104104...
hello world!
hello world!
hello world!
Finished. The state of the machine is: 2
p: 3 pe: 3
Running the state machine with input 104120104...
hello world!
Finished. The state of the machine is: 0
p: 1 pe: 3
</code></pre>
<p>When we pass &#8220;hhh&#8221;, we get a &#8220;hello world!&#8221; for each &#8220;h&#8221;. When we pass &#8220;hxh&#8221;, we get the first &#8220;hello world!&#8221;, but when we hit the &#8220;x&#8221; we enter the error state, so the last &#8220;h&#8221; doesn&#8217;t get evaluated.</p>
<p>Here&#8217;s one more <a href="http://dev.agent.ie/svn/ragel/examples/multiple_state_machine.rl">example</a>, this time without defining a run_machine method:</p>
<pre><code>  %%{
    machine hello_and_welcome;
    main := ( 'h' @ { puts "hello world!" }
            | 'w' @ { puts "welcome" }
            )*;
  }%%
    data = 'whwwwwhw'
    %% write data;
    %% write init;
    %% write exec;
</code></pre>
<p><img id="image118" src="http://www.devchix.com/wp-content/uploads/2007/12/multiple_state_machine.png" alt="Hello and Welcome State Machine" /></p>
<pre><code>welcome
hello world!
welcome
welcome
welcome
welcome
hello world!
welcome
</code></pre>
<p>So, there you go. Hours of entertainment await you. We&#8217;ve only scratched the surface of Ragel&#8217;s features here, but you should now be able to navigate through the User Guide without too much trouble. If you need a better reason than &#8220;fun&#8221; to play with Ragel, then bear in mind that parsers are a great tool for constructing Domain Specific Languages (DSLs), and state machines are magic code shrinking machines for situations where you need to keep track of the, er, state of something and control the transitions between states (i.e. business logic). I would highly recommend everyone to read <a href="http://www.zedshaw.com/tips/ragel_state_charts.html">this article about Ragel</a> which inspired me to check it out. If you&#8217;re into Rails, then take a look at the acts_as_state_machine plugin which might be more intuitive than Ragel at first. If the DSL angle is more your cup of tea then you might want to look at <a href="http://www.antlr.org/">ANTLR</a> instead, which has a different focus and feature set than Ragel.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/01/13/a-hello-world-for-ruby-on-ragel-60/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Programming from the (under)ground up</title>
		<link>http://www.devchix.com/2008/01/05/programming-from-the-underground-up/</link>
		<comments>http://www.devchix.com/2008/01/05/programming-from-the-underground-up/#comments</comments>
		<pubDate>Sun, 06 Jan 2008 01:25:04 +0000</pubDate>
		<dc:creator>lisa</dc:creator>
		
		<category><![CDATA[Apprenticeship]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/01/05/programming-from-the-underground-up/</guid>
		<description><![CDATA[     Hello. Welcome to my first article.
     And my brand spankin new, made-from-scratch stab at programming. It&#8217;s going to be a bumpy ride: bumpy like fun-old-rollercoaster-bumpy not trainwreck-bumpy (universe willing).
     Please allow me to rattle off some quick background facts so you know [...]]]></description>
			<content:encoded><![CDATA[<p>     Hello. Welcome to my first article.</p>
<p>     And my brand spankin new, made-from-scratch stab at programming. It&#8217;s going to be a bumpy ride: bumpy like fun-old-rollercoaster-bumpy not trainwreck-bumpy (universe willing).</p>
<p>     Please allow me to rattle off some quick background facts so you know what planet I&#8217;m coming from. I&#8217;m a 26 year old retired bartender. I did that for more years than I care to say (ok fine, 8). I fancy myself an amateur artist; basically, I paint for therapy and fun. I&#8217;ve always liked things of a nerdy nature (i.e. writing very basic html in a webshell on angelfire when I was 13, Magic the Gathering, guys who majored in Astrophysics, etc). I consider myself very confident and intelligent, and it&#8217;s a shame that went to waste for so many years. That being said, years of bartending with no substantial plans for the future wore me out and made me feel quite desperate for awhile.</p>
<p>     Then something changed. I got beat down so much by the universe&#8217;s way of telling me to stop f&#8217;ing around, that I got fed up with being fed up. Well, Desi McAdam happens to be one of my favorite people on the planet and a very close friend, and she had always offered to teach me programming&#8230;intensively. She and my other longtime friend/ROR evangelist Obie Fernandez had always told me they thought I&#8217;d be a great programmer. I didn&#8217;t know what they were talking about. So I called up my dear Desi and said &#8220;I&#8217;ll do whatever it takes. Let&#8217;s do this thing.&#8221;</p>
<p>     I thought I was going to be learning in my off time while still bartending and getting tutored whenever Desi was in town. I knew this would take a very, very, very long time, but I felt ready for the challenge.</p>
<p>     As it turned out, she and Obie were down here in Florida on the beach working with this fabulous guy Mark Smith. I had met him some weeks before, and we all had a great time together. They wanted to bring an apprentice on to the small team, so voila! Here I am. I am now in full on training starting with nothing but my instinctual and intellectual abilities and no experience. I am extremely grateful for the opportunity I have, and I intend to give back to Desi and Obie by trying hard to be a bad ass programmer.</p>
<p>     Desi is putting alot of effort into being my personal, full-time tutor, and I think she rocks socks for it.</p>
<p>     So I&#8217;m offering up myself, my victories, and my many future foibles here for your musing and amusement.</p>
<p>     Cheers and enjoy</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/01/05/programming-from-the-underground-up/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Migrating from Test::Unit to RSpec</title>
		<link>http://www.devchix.com/2008/01/04/migrating-from-testunit-to-rspec/</link>
		<comments>http://www.devchix.com/2008/01/04/migrating-from-testunit-to-rspec/#comments</comments>
		<pubDate>Fri, 04 Jan 2008 17:08:06 +0000</pubDate>
		<dc:creator>jacqui</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Testing]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2008/01/04/migrating-from-testunit-to-rspec/</guid>
		<description><![CDATA[At Streeteasy, nearly half of our tests are still written in Test::Unit, so it&#8217;s hard to see what our actual test coverage is using Rcov.
I read recently that RSpec got support for Test::Unit interoperability. Obviously now is the time to make the switch from Test::Unit to RSpec. You can do it without a mass exodus [...]]]></description>
			<content:encoded><![CDATA[<p>At <a href="http://www.streeteasy.com/">Streeteasy</a>, nearly half of our tests are still written in <a href="http://ruby-doc.org/stdlib/libdoc/test/unit/rdoc/index.html">Test::Unit</a>, so it&#8217;s hard to see what our actual test coverage is using <a href="http://eigenclass.org/hiki.rb?rcov">Rcov</a>.</p>
<p>I read recently that <a href="http://www.rubyinside.com/rspec-11-released-now-supports-rails-20-674.html">RSpec got support for Test::Unit interoperability</a>. Obviously now is the time to make the switch from Test::Unit to RSpec. You can do it without a mass exodus from Test::Unit. Use your existing tests inside the RSpec test harness.</p>
<p>So here&#8217;s how I converted all out legacy tests to rspec.</p>
<h1>Step One: update RSpec</h1>
<p>This is fairly self-explanatory and written up <a href="http://rspec.info/upgrade.html">elsewhere</a>. However, in short, I updated both our rspec and rspec_on_rails plugins, remembering to rerun </p>
<p><code>$ ruby script/generate rspec</code></p>
<p>Make a back-up copy of the spec_helper if you&#8217;ve customized it. Compare it to the one generated for the new rspec version to see if there&#8217;s been any significant changes, and if so, merge them into your helper.</p>
<h1>Step Two: move your files from test/ to spec/</h1>
<p>This is what I did: I copied test/unit/* to spec/models/, renaming them appropriately:</p>
<p><code>
<pre>
  ## current_path is a hash where :tu =&gt; test::unit path and :s =&gt; spec path
  def make_tests_specs(current_path)
    current_path[:tu].each do |file|
      unless file == &#8220;.&#8221; or file == &#8220;..&#8221;
        full_file = File.join(current_path[:tu].path, file)
        if File.directory? full_file
          spec_file = full_file.gsub(/test/, &#8220;spec&#8221;)
          spec_file.gsub!(/unit/, &#8220;models&#8221;)
          spec_file.gsub!(/functional/, &#8220;controllers&#8221;)
          FileUtils.mkdir_p(spec_file) unless File.exists? spec_file
          make_tests_specs({:tu =&gt; Dir.new(full_file), :s =&gt; Dir.new(spec_file)})
        else
          new_spec = File.join(current_path[:s].path, file.gsub(/_test/, &#8220;_spec&#8221;))
          puts &#8220;converting TestCase #{full_file} to ExampleGroup #{new_spec}\n&#8221;
          File.copy(full_file, new_spec)
        end
      end
    end
  end
</pre>
<p></code></p>
<h1>Step Three: change your assertions</h1>
<p>While that would move all my tests over to the specs directory and rename them, I figured, why should I stop there? I realized I could probably do a lot of the Test::Unit to RSpec syntax conversions programmatically. Here are the regular expressions I used to do the substitutions - while these worked great for our codebase at StreetEasy, your mileage may vary, so be sure to use caution before running this against your code base (and hey, you do use source control, don&#8217;t you?):</p>
<p><code>
<pre>
if line =~ %r@require.*?test_helper@
  new_file.puts "require '#{RAILS_ROOT}/test/test_helper'"
  new_file.puts "require '#{RAILS_ROOT}/spec/spec_helper'"
elsif line =~ %r@class.*?TestCase@ and line !~ %r@Controller@
  new_file.puts "describe 'transitioning from TestCase to ExampleGroup' do"
elsif line =~ %r@class\s*(.*?)Test@
  new_file.puts "describe #{$1}, 'transitioning from TestCase to ExampleGroup' do"
  new_file.puts "integrate_views"
elsif line =~ %r@def setup@
  new_file.puts "before do"
elsif line =~ %r@def test_(.*?)\n@
  new_file.puts "it \"should #{$1.humanize.downcase}\" do"
elsif line =~ %r@assert_response :success@
  new_file.puts "response.should be_success"
elsif line =~ %r@assert_response :redirect@
  new_file.puts "response.should be_redirect"
elsif line =~ %r@assert_redirected_to (.*?)\n@
  new_file.puts "response.should redirect_to(#{$1})"
elsif line =~ %r@assert_equal (.*?),\s(.*?)\n@
  m1 = $1
  m2 = $2
  unless m1.nil? or m2.nil?
    unless m1.match(/nil/) or m2.match(/nil/)
      new_file.puts "#{m1}.should == #{m2}"
    end
  end
elsif line =~ %r@assert assigns\(:(.*?)\)$@
  new_file.puts "assigns[:#{$1}].should be_true&#8221;
else
  unless line =~ /^class.*?Controller.*?rescue_action.*?end$/i or line =~ /require &#8216;.*?_controller&#8217;/i or line =~ /^#/
    new_file.puts line
  end
end
</pre>
<p></code></p>
<p>The above block of code will convert any response (:success, :redirect, redirect_to), assigns, and equality assertions. It will change your method declarations to &#8220;it &#8217;should&#8230;&#8217; do/end&#8221; block syntax. It will require both the test_helper and spec_helper. It will integrate_views by default on your functional (controller) tests; you might want to go through those by hand later and separate out the front-end stuff into a set of <a href="http://errtheblog.com/posts/66-view-testing-20">view tests</a>, depending on <a href="http://tuples.us/2007/08/17/my-life-with-bdd-and-rspec/">how you</a> <a href="http://rubyforge.org/pipermail/rspec-users/2007-August/002769.html">feel about</a> <a href="http://rspec.info/documentation/rails/writing/views.html">them</a>. </p>
<p>You could definitely write more substitutions - there are more assertions in Test::Unit, of course. If your code base makes extensive use of other assertions you&#8217;ll probably want to add to the regexes above. In our case, however, I found the above satisfied converting the most straight-forward Test::Unit assertions, leaving me with the slightly more complicated examples to convert by hand, which brings me to the next step. </p>
<p>FYI, you can find a table of Test::Unit assertions and their RSpec equivalents <a href="http://rspec.info/documentation/test_unit.html">here on the RSpec documentation site</a>.</p>
<h1>Step Four: run rake:spec and see what happens</h1>
<p>You might as well see what situation any automated conversion process left you in. I had a few errors during this phase - mostly due to the fact that I forgot to move my fixtures, woops - but it didn&#8217;t take me very long to resolve them.</p>
<h1>Step Five: go through each sparkling new spec and convert any remaining Test::Unit-based assertions into RSpec syntax.</h1>
<p>The good news: you can take your time on this step since RSpec now plays nice with Test::Unit. I was in a particularly motivated and productive mood after finding myself with a big directory full of specs (and an amazingly empty test/ directory) so I just went through them all right then and there. It took me most of the afternoon, but when I left work that day I was able to see this, which is just awesome:</p>
<p><code><br />
$ rake spec<br />
........................................................................................................................................................................................................................................................................................................................................................................................................................................................</p>
<p>Finished in 70.023361 seconds</p>
<p>440 examples, 0 failures<br />
</code></p>
<p>As you can see from the amount of time it took all 440 examples to run, we could definitely benefit from a greater use of mocks and stubs in our controller tests. 70 seconds is a tad bit long. That&#8217;s next on the to do list - mock and stub wherever I can in our controller tests, followed by integration/big picture testing using Story Runner, and then, if there&#8217;s time*, refactor our specs to be better organized and efficient - I can think of several places where I had wished for nested examples, or could have used shared examples, had I been aware they existed at the time.</p>
<p>I&#8217;ll be writing up my experience with Story Runner in the next couple of weeks. Til then, though, best of luck in your specs!</p>
<p>* always a compromise when you&#8217;re trying to do things the right way and add business value simultaneously.</p>
<p>For more information Behavior Driven Development, check out <a href="http://dannorth.net/">Dan North</a>&#8217;s article, &#8220;<a href="http://dannorth.net/introducing-bdd">Introducing BDD</a>.&#8221;</p>
<p>You can find the documentation for RSpec at <a href="http://rspec.info/index.html">http://rspec.info</a>.</p>
<p>Many thanks to Joshua Sierles, Paul Marsh, and Josh Knowles for their time in reviewing this!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/01/04/migrating-from-testunit-to-rspec/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RubyEast Recap, Slides, and Other Thoughts</title>
		<link>http://www.devchix.com/2007/09/30/rubyeast-recap-slides-and-other-thoughts/</link>
		<comments>http://www.devchix.com/2007/09/30/rubyeast-recap-slides-and-other-thoughts/#comments</comments>
		<pubDate>Sun, 30 Sep 2007 22:25:25 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Apprenticeship]]></category>

		<category><![CDATA[Presentation]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Testing]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/09/30/rubyeast-recap-slides-and-other-thoughts/</guid>
		<description><![CDATA[I spoke at RubyEast this past Friday and I think the presentation went pretty well. It was my first presentation in a speaker/audience type setting so I was very nervous. I have presented at Agile 2006 but it was a game (interactive) and was co-presented by several other people. This presentation was the first time [...]]]></description>
			<content:encoded><![CDATA[<p>I spoke at RubyEast this past Friday and I think the presentation went pretty well. It was my first presentation in a speaker/audience type setting so I was very nervous. I have presented at Agile 2006 but it was a game (interactive) and was co-presented by several other people. This presentation was the first time I stood in front of a room full of people and spoke and everything went very well. Like I said I was really nervous but as soon as I got started the nervousness went away. I think I am very lucky because I was able to present to a room full of very nice/cool people and that made the experience a great one. I want to actually thank the people who came to hear me present and who gave me great feedback and encouragement afterwards it really made my day.  If you are interested here are the slides for the presentation. <a href="http://www.devchix.com/wp-content/uploads/2007/09/atourofrailstesting-rspec.pdf">A Tour Of Rails Testing using RSpec</a></p>
<p>I didn&#8217;t get to see many of the sessions because I was busy preparing for my talk but I was able to catch <a href="http://www.jroller.com/obie/entry/obie_s_rubyeast_2007_presentations">Obie&#8217;s presentation - Advanced ActiveRecord</a> which was really good (and I am not just saying that because he is my boyfriend). I also caught the ending Keynote where Nap (I actually don&#8217;t know his real name) announced the Rails Rumble winners. There were several screencasts and it made me wish that Obie, Clay, Nick and I would have had time to get the video that was shot of us over the weekend edited and ready for prime time.  We had a blast doing the competition and while we didn&#8217;t win (we got honorable mention) we learned a lot and I think we all grew closer in those 48 hours. The teams that did win did a tremendous job on their apps and well deserved the loot. Take a look at the winners there really are some great apps. <a href="http://railsrumble.com/2007/9/28/and-the-envelope-please">Rails Rumble Winners</a></p>
<p>Friday evening a bunch of people got together after the conference and played several games of Werewolf which is a really fun game to play. I got to know a lot of people during that game and it was a great way to wind down. </p>
<p>Couple of other thoughts before I end the post. <a href="http://shesgeeky.org/">ShesGeeky (un)Conference</a> sounds like it is going to kick major ass so any of you ladies out there who can attend make sure you get registered. Additionally, ladies if you want to talk during the conference please contact the organizers. </p>
<p>GrrrlCamp seems to be getting a good footing. I was lucky enough to meet THE Gloria this past Friday and I look forward to being a part of GrrlCamp.</p>
<p>I have taken on an apprentice and she will soon be posting to the blog about her experiences. I am in the process of trying to see if creating an apprenticeship type program run by DevChix is possible because after speaking with Sonia (one of the women on DevChix) she helped me figure out that I would really like to have a program that fits the apprenticeship model rather than a mentoring program. Look for more to come on this in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/09/30/rubyeast-recap-slides-and-other-thoughts/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Ruby East Registration Open</title>
		<link>http://www.devchix.com/2007/08/16/ruby-east-registration-open/</link>
		<comments>http://www.devchix.com/2007/08/16/ruby-east-registration-open/#comments</comments>
		<pubDate>Thu, 16 Aug 2007 16:53:45 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/2007/08/16/ruby-east-registration-open/</guid>
		<description><![CDATA[Ruby East registration is open. It is a one day Philadelphia based Ruby on Rails Conference that is being held 9/28. They have limited space so if you are planning to go you should probably go ahead and register. I am pretty happy to say that there will be 3 DevChix members presenting at the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.ruby-east.com">Ruby East</a> registration is open. It is a one day Philadelphia based Ruby on Rails Conference that is being held 9/28. They have limited space so if you are planning to go you should probably go ahead and register. I am pretty happy to say that there will be 3 DevChix members presenting at the conference. I think it will be a great day.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2007/08/16/ruby-east-registration-open/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
