<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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:sy="http://purl.org/rss/1.0/modules/syndication/" 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, 04 Jul 2009 06:18:34 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<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>RailsBridge</title>
		<link>http://www.devchix.com/2009/05/04/railsbridge/</link>
		<comments>http://www.devchix.com/2009/05/04/railsbridge/#comments</comments>
		<pubDate>Mon, 04 May 2009 15:55:10 +0000</pubDate>
		<dc:creator>gloriajw</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=270</guid>
		<description><![CDATA[Even though I am a Python developer, this made me happy:

http://railsbridge.org/
We&#8217;ve been fortunate to have an outstanding, welcoming Python community driving the tone and the quality of events from PyCon, down to the statewide and local user groups. We don&#8217;t yet have a need for such a bridge group, and I hope we never need [...]]]></description>
			<content:encoded><![CDATA[<p>Even though I am a Python developer, this made me happy:</p>
<p><a href="http://railsbridge.org/"><br />
http://railsbridge.org/</a></p>
<p>We&#8217;ve been fortunate to have an outstanding, welcoming Python community driving the tone and the quality of events from PyCon, down to the statewide and local user groups. We don&#8217;t yet have a need for such a bridge group, and I hope we never need one. But it&#8217;s great to see one form quickly where it&#8217;s needed, and to see familiar names associated with it. More power to you.</p>
<p>Gloria</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/05/04/railsbridge/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Hpricot and woot!</title>
		<link>http://www.devchix.com/2009/01/13/hpricot-and-woot/</link>
		<comments>http://www.devchix.com/2009/01/13/hpricot-and-woot/#comments</comments>
		<pubDate>Tue, 13 Jan 2009 15:00:45 +0000</pubDate>
		<dc:creator>Angel N. Sciortino</dc:creator>
		
		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=196</guid>
		<description><![CDATA[I know there are several sites for tracking wootoffs on Woot, but I wanted to write my own small program in Ruby. To do this, I used Hpricot by why the lucky stiff.
First, I need my require statements. I&#8217;ll need rubygems, since hpricot is a gem, and open-uri to access woot.

require 'rubygems'
require 'hpricot'
require 'open-uri'

Woot has [...]]]></description>
			<content:encoded><![CDATA[<p>I know there are several sites for tracking wootoffs on <a href="http://www.woot.com">Woot</a>, but I wanted to write my own small program in Ruby. To do this, I used <a href="http://github.com/why/hpricot/tree/master">Hpricot</a> by <a href="http://www.whytheluckystiff.net/">why the lucky stiff</a>.</p>
<p>First, I need my require statements. I&#8217;ll need <code>rubygems</code>, since <code>hpricot</code> is a gem, and <code>open-uri</code> to access woot.</p>
<pre>
require 'rubygems'
require 'hpricot'
require 'open-uri'
</pre>
<p>Woot has an API that returns XML, so I used <code>Hpricot::XML</code> to parse what comes back.</p>
<pre>
doc = Hpricot::XML(open("http://www.woot.com/salerss.aspx"))
</pre>
<p>Now I want to know if it&#8217;s a wootoff. If it is, I&#8217;ll want to check more frequently. I use the <code>at</code> method to find the element I want, and <code>inner_html</code> to get the text inside that element. The element I&#8217;m interested in is <code>woot:wootoff</code>. I&#8217;m going to start putting the output into the <code>text</code> variable.</p>
<pre>
wootoff = doc.at("woot:wootoff").inner_html =~ /true/i
text = wootoff ? "wootoff! ^_^" : "no wootoff v_v"
text << "\n"
</pre>
<p>Next I want to know what the item is and the price and shipping.</p>
<pre>
text << doc.at("item > title").inner_html << "\n"
text << doc.at("woot:price").inner_html << " + "
text << doc.at("woot:shipping").inner_html << "\n"
</pre>
<p>I&#8217;ll also want to know how much of the item is left, so I know if I need to rush to buy something I want.</p>
<pre>
percent_gone = doc.at("woot:soldoutpercentage").inner_html
percent_gone = percent_gone.to_f * 100
percent_left = (100 - percent_gone).round
text << "#{percent_left}% Left"
</pre>
<p>I took all that code and put it into a method, to be looped over every two minutes. I wanted it to print to the screen only if the text changed. This is what the completed program looks like.</p>
<pre>
#!/usr/bin/ruby
require 'rubygems'
require 'hpricot'
require 'open-uri'

def woot_item
  doc = Hpricot::XML(open("http://www.woot.com/salerss.aspx"))
  wootoff = doc.at("woot:wootoff").inner_html =~ /true/i
  text = wootoff ? "wootoff! ^_^" : "no wootoff v_v"
  text << "\n"
  text << doc.at("item > title").inner_html << "\n"
  text << doc.at("woot:price").inner_html << " + "
  text << doc.at("woot:shipping").inner_html << "\n"
  percent_gone = doc.at("woot:soldoutpercentage").inner_html
  percent_gone = percent_gone.to_f * 100
  percent_left = (100 - percent_gone).round
  text << "#{percent_left}% Left"
end

woot_text = ''
while true
  new_woot_text = woot_item
  if woot_text != new_woot_text
    woot_text = new_woot_text
    puts "*****************************************************"
    puts woot_text
  end
  sleep 120
end
</pre>
<p>Here is some output from the program.</p>
<pre>
*****************************************************
no wootoff v_v
Lockjaw Self-Adjusting Locking Pliers - 2 Pack
$9.99 + $5 shipping
100% Left
</pre>
<p>Of course, this is only a beginning to what you can do. You can have it send a twitter, SMS, email, or any number of things if an item you want is available or a wootoff starts.</p>
<p>Angel</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2009/01/13/hpricot-and-woot/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to see exception_notification plugin work in development mode.</title>
		<link>http://www.devchix.com/2008/12/09/how-to-see-exception_notification-plugin-work-in-development-mode/</link>
		<comments>http://www.devchix.com/2008/12/09/how-to-see-exception_notification-plugin-work-in-development-mode/#comments</comments>
		<pubDate>Tue, 09 Dec 2008 13:53:30 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=190</guid>
		<description><![CDATA[I use HopToad by the Thoughtbot Guys (I say guys because I know they don&#8217;t have any girls on the team *wink*) to handle exceptions from my rails apps these days but today I found myself in a situation where I needed to use the exception_notification plugin instead. I haven&#8217;t used the plugin for quite [...]]]></description>
			<content:encoded><![CDATA[<p>I use <a href="http://www.hoptoadapp.com/welcome">HopToad</a> by the <a href="http://thoughtbot.com/">Thoughtbot Guys</a> (I say guys because I know they don&#8217;t have any girls on the team *wink*) to handle exceptions from my rails apps these days but today I found myself in a situation where I needed to use the <a href="http://github.com/rails/exception_notification/tree/master">exception_notification plugin</a> instead. I haven&#8217;t used the plugin for quite sometime so I wanted to make sure I had everything all setup correctly before pushing out to staging and production. I remembered that I had done this before in development but I couldn&#8217;t remember everything I needed to do so I, of course, asked uncle Google. After reading the readme and a little googling I figured out what I needed to do in order to see it work in development. It took me far longer than I wanted and I don&#8217;t want to go through that again in the future so I figured I would just write a quick blog post to remind me next time I want to do it.</p>
<p>So here goes:</p>
<p><strong>First get Exception notification all setup (this is all from the readme file)</strong></p>
<p><code>script/plugin install git://github.com/rails/exception_notification.git </code></p>
<p>then in application.rb put<br />
<code>include ExceptionNotifiable</code></p>
<p>then in environment.rb  put<br />
<code>ExceptionNotifier.exception_recipients = %w(joe@schmoe.com bill@schmoe.com)</code></p>
<p><strong>Once you have it setup you can do all the other stuff that lets you see it work in your development environment.</strong></p>
<p>put the following two lines in your application.rb file<br />
<code>alias :rescue_action_locally :rescue_action_in_public<br />
local_addresses.clear</code></p>
<p>then in your development.rb file change<br />
<code>config.action_controller.consider_all_requests_local = true</code><br />
to be<br />
<code>config.action_controller.consider_all_requests_local = false</code></p>
<p>Exception Notifier doesn&#8217;t send email notification on ActiveRecord::RecordNotFound and ActionController::UnknownAction errors. So you will need to create 500 error to see the notification going out in your log. You can just add an action to a controller that throws a divide by zero error, restart your server and hit that action and you should see the notification trigger in your development log.</p>
<p>Once you have seen it work make sure to undo everything in the second section.</p>
<p>Cheers</p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/12/09/how-to-see-exception_notification-plugin-work-in-development-mode/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Rails Summit Latin America</title>
		<link>http://www.devchix.com/2008/10/16/rails-summit-latin-america/</link>
		<comments>http://www.devchix.com/2008/10/16/rails-summit-latin-america/#comments</comments>
		<pubDate>Thu, 16 Oct 2008 20:58:09 +0000</pubDate>
		<dc:creator>desi</dc:creator>
		
		<category><![CDATA[Events]]></category>

		<category><![CDATA[Introductions]]></category>

		<category><![CDATA[Presentation]]></category>

		<category><![CDATA[Python]]></category>

		<category><![CDATA[Rails]]></category>

		<category><![CDATA[Reviews]]></category>

		<category><![CDATA[Ruby]]></category>

		<category><![CDATA[Thoughts]]></category>

		<category><![CDATA[Tips and Tricks]]></category>

		<guid isPermaLink="false">http://www.devchix.com/?p=183</guid>
		<description><![CDATA[I am currently in Sao Paulo, Brazil at Rails Summit Latin America and the experience has been great thus far.
Ladies at the conference there is information at the end of this writeup about how to join. If you don&#8217;t feel like reading everything in this writeup that is fine but please do read about joining. [...]]]></description>
			<content:encoded><![CDATA[<p>I am currently in Sao Paulo, Brazil at <a href="http://www.locaweb.com.br/railssummit/default.asp?language=7">Rails Summit Latin America</a> and the experience has been great thus far.</p>
<p><b><i>Ladies at the conference there is information at the end of this writeup about how to join. If you don&#8217;t feel like reading everything in this writeup that is fine but please do read about joining.</i></b> </p>
<p>In contrast to many conferences I have been to recently I have been to just about every talk at this conference and I have thoroughly enjoyed them all. I say just about because there is a second track that is going on in another room but I haven&#8217;t been to those sessions. </p>
<p><b>The Organizers:</b><br />
<a href="http://www.akitaonrails.com/"> Fabio Akita and Gilberto Mautner Founder of <a href="http://www.locaweb.com.br/portal.html">locaweb </a> have done a great job with the conference and I would like to give them a special thanks. The lineup, venue and everything has been great. Obrigado!</p>
<p><b>Theme:</b><br />
I think most conferences, through the keynotes, some how seem to create a theme. The theme that I am picking up on at this conference is this: &#8220;Have No Fear&#8221; and &#8220;Just Do It&#8221;. No one actually said either of those two things but thats basically what I am taking away from most of the keynotes. They have all been especially encouraging for people to become involved. Contribute, create, and code. Give back to the community and get involved. Don&#8217;t be afraid .. put yourself out there and learn from the feedback you get.. learn from the experiences of creating.. do side projects.. basically be PASSIONATE.</p>
<p><b>The Talks:</b><br />
All the talks I have seen have been excellent. I give them an excellent rating because they have all had the qualities I look for in a talk.<br />
1. The content is good and interesting.<br />
2. The delivery of that content is entertaining or at least engaging.</p>
<p><b>Chad Fowler</b> - I really enjoyed Chad&#8217;s talk and as I sit here I am struggling to figure out a way to describe his talk and actually do it justice. He spoke about his background in music and how that has translated to his life as a developer. In addition, he spoke about being remarkable. He talked about many ways in which people are remarkable and many ways in which we ourselves can become remarkable people. He touched on many things and did so in such a way that I was able to stay engaged with him. There were pictures and video&#8217;s and graphs and fake numbers and.. anyway about the best I can say is that I personally really enjoyed his talk.</p>
<p><b>Dr. Nic Williams</b> - Dr. Nic&#8217;s presentation is a little easier to sum up but at the same time I can&#8217;t really do it justice. Dr. Nic is one of those speakers that if you ever have a chance to see him speak you should definitely take the opportunity. He is hilarious and has a good message. His talk was all about how to contribute back.. how to get involved.. how to participate. Make the future you proud of the you now.   <a href="http://drnicwilliams.com/2007/08/20/newgem-using-rubigen-for-generator-support/">Dr. Nic also talked about newgem</a></p>
<p><b>Chris Wanstrath</b> - Chris&#8217;s keynote started off being about the future of Ruby and RoR but in the end he took it back to the past and where we have come from. He went through a great deal of history on how we got here which I personally enjoyed especially when he pointed out the first ENAIC programmers were all women, unfortunately he was speaking quite fast so I think a lot of his talk was lost in translation. I think the primary thing Chris was trying to get across is to not be afraid. If you have an idea.. make time to get to it you never know where thats going to go. In the very least you gain experience and you gain knowledge. <a href="http://www.github.com">Chris has had many projects in the past but his current claim to fame is all about github.</a></p>
<p><b>Jay Fields</b> - Jay&#8217;s talk was about the immaturity of testing as a whole. While I agree with some of the things he said I also disagree with some of the things he said. I have had the luxury of getting to pair with Jay on projects before and its always interesting for me to see him speak because I have first hand experience with a lot of things he talks about. He described the problem of immaturity in testing as a whole first with the fact that we can&#8217;t even agree on common terminology. He then proceeded to talk about various tools and the pros and cons of each. He covered Selenium, Test:Unit, Rspec, Syntasis, and Expectations. The last two being the most immature of them all and bleeding edge. i.e. use at your own risk. He also answered a few questions about how to make your test suite fun faster and his response was basically that if you are willing to deal with the pain that goes along with it there are tools you can look into using such as null_db, unit_record, and ARBS. You can read about them on <a href="http://agilewebdevelopment.com/plugins/nulldb"> the null_db page on Agile Web Development site</a>. That page links out to the other plugins.  Jay also pointed out that all the things he was talking about are from his point of view. In other words its the context in which he works that causes him to have some of the testing beliefs he has.</p>
<p><b>David Chemlisky</b> - David&#8217;s first talk was about doing TDD and in my opinion he did an excellent job of demonstrating TDD. I have seen him give a talk similar in the past and of all the people I have heard try to describe TDD, David is one of the most skilled at it. He gave the talk from the point of view of a teacher which in my opinion is really the only way you can truly explain TDD. He went through the process step by step with us all to show us the way. :)</p>
<p>His second talk was more about Acceptance testing and story runner and the newest version of story runner which is being called cucumber. He demonstrated how it worked and made sure to give context around all the terminology such as user stories etc. Hopefully there will be some way of seeing this talk again maybe through a screen cast or something of that nature. I&#8217;ll be sure to ask him if he would be willing to do that. Or maybe there is one with cucumber? Not sure haven&#8217;t had a chance to look yet.<br />
Couple of links to stuff he talked about.<br />
<a href="http://github.com/aslakhellesoy/cucumber/wikis/home">Cucumber</a><br />
<a href="http://github.com/brynary/webrat/tree/master">webrat on github</a> and <a href="http://movesonrails.com/articles/2008/08/19/webrat-story-steps">a blog post on it here</a></p>
<p>On that last note I am actually interested to know if these talks are being recorded and if they will be available somewhere?  Anyone know the answer to that?</p>
<p><b>Obie Fernandez</b> - I haven&#8217;t actually seen Obie give his talk yet but I have seen the talk (insider information) so I am going to go ahead and give a recap.. I asked him to plug DevChix and wanted to have this write up already done before he did so.. ;-)  So Obie&#8217;s talk will be about the &#8220;Hashrocket Way&#8221;. He is basically giving up our secrets.. Like Dr. Nic said no secrets!  His main focus will be around how we work, the fact that we follow Agile Tenants and that we value fun, collaboration, and effectiveness. We achieve those things through certain practices such as pair programming, TDD, Story Carding, launch parties etc. <a href="http://blog.obiefernandez.com">Again you should check out his blog.</a></p>
<p><b>Ninh Bui and Hongli Lai a.k.a The Phusion Guys</b> - I woke up late so I didn&#8217;t catch all of the talk from the Phusion guys but the part that I did catch was hilariously funny and explained things like caching and database sharding. Additionally, they gave a demo of <a href="http://github.com/FooBarWidget/yuumius_comments/tree/master"> yuumis_comments..</a> and <a href="http://blog.phusion.nl/">here is also a link to their blog</a> </p>
<p>I call out all of these guys because they are some of the best speakers I have ever seen and I actually saw them speak at this particular event. </p>
<p><b>Phillippe Hanrigou</b> - Phillippe is going to be giving a talk on how to effectively do acceptance testing which I am looking forward to but I won&#8217;t be able to cover that here because I haven&#8217;t seen it and since I don&#8217;t have insider info on that one I&#8217;ll just have to wait like everyone else. I do know that he will be talking about one tool I hadn&#8217;t heard of before called <a href="http://deep-test.rubyforge.org/">Deep Test</a>. <a href="http://ph7spot.com">You should check Phillippe&#8217;s blog as well</a></p>
<p><b>Luis Lavena</b> - Luis will also be giving a talk about surviving with RoR and Ruby as a windows user.. again I think the talk is going to be awesome but its in the future so I can&#8217;t really talk about that yet. <a href="http://blog.mmediasys.com/">You should check out his blog!</a></p>
<p><b>The Venue:</b><br />
The venue is quite nice. The main auditorium is very well arranged and has plenty of room despite the fact that there are a lot of people here. There is a very large screen making it easy for everyone to see the slides as well as the speakers. The lighting on the actual speakers is a little weird but other than that the actual conference room is great. The audio is fantastic and the actual hang out area is quite nice as well (other than the lack of air conditioning but thats just me being a little whiny its not really that hot). One other really important point that I want to bring up is the translators. You can get a headset at the checkin area that will translate the talks from English to Spanish and Portuguese and from what I understand the translators have been doing a kick ass job so a special thanks to all those ladies in the booths translating for us. </p>
<p><b>The Community:</b><br />
I was very encouraged by the number of people at the conference, the number of people using github (vast majority) and the number of people doing Ruby and RoR development on a day to day basis. It is always an exciting moment for me when I realize it is gaining in support because how much I love the language. In addition, everyone has been extremely helpful and friendly. We meet <a href="http://www.karmacrash.com/">Tim Case</a> the first day and he was more than willing to take us under his wing and show us around. </p>
<p>One thing that was both encouraging and discouraging is the number of women at the conference. There were women, thats the good news, the bad news is that I think from a ratio point of view the number of women at the conference is on par with what I have experienced at Ruby and RoR conferences in the US. That is to say its pretty small. Usually at conferences since there are so few women I can manage to talk to most of them and but here I have been some what intimidated by the language barrier. One other thing to point out is that there were no women speakers but hey that isn&#8217;t really that uncommon. I am hoping that when Obie does his talk and plugs DevChix for us that many of those women who were at the conference that I didn&#8217;t get to meet will come to the site and join.</p>
<p><b>Ladies Please Read</b><br />
For those women who do happen to come to the site from Brazil and other countries. I would like to say that we have members world wide who can speak a number of different languages so please don&#8217;t let that discourage you from joining and participating. We would LOVE to have you all as part of the group. Also encourage other female developers you know.</p>
<p>If you are a women, a developer, interested in joining and/or contributing to DevChix, please contact Desi McAdam at info(-at-)devchix.com with your:</p>
<p>   1. Name<br />
   2. Email<br />
   3. Do you know any one from DevChix?<br />
   4. A short 2 sentence bio describing your development background/experience (or what you hope to learn) and a link to your blog if you happen to have one.</p>
<p>Obrigado! :) </p>
]]></content:encoded>
			<wfw:commentRss>http://www.devchix.com/2008/10/16/rails-summit-latin-america/feed/</wfw:commentRss>
		</item>
		<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[Introductions]]></category>

		<category><![CDATA[Python]]></category>

		<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. A version of this tutorial in Portuguese is available here.
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 [...]]]></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. A version of this tutorial in Portuguese is available <a href="http://artigos.waltercruz.com/a-hello-world-for-ruby-on-ragel/">here</a>.</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://ananelson.com/blog/2008/01/simple_state_machine.rl">here</a>.</p>
<p>The first step, of course, is installing Ragel. The <a href="http://www.complang.org/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>http://svn.complang.org/ragel/trunk/</code></pre>
<p>As usual the test/ directory is your friend, also check out the examples/ directory. As per <a href="http://www.complang.org/pipermail/ragel-users/2007-June/000252.html">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://ananelson.com/blog/2008/01/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 src="http://ananelson.com/blog/2008/01/simple_state_machine.jpg" 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://ananelson.com/blog/2008/01/never_ending_simple_state_machine.jpg" 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://ananelson.com/blog/2008/01/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 src="http://www.ananelson.com/blog/2008/01/multiple_state_machine.jpg" 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://zedshaw.com/essays/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>
	</channel>
</rss>
