<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>chatr - Tastes Great, Doesn't Leave a Bruise!</title>
 <link href="http://abedra.github.com/atom.xml" rel="self"/>
 <link href="http://abedra.github.com/"/>
 <updated>2010-08-07T13:36:36-07:00</updated>
 <id>http://abedra.github.com/</id>
 <author>
   <name>Aaron Bedra</name>
   <email>aaron@aaronbedra.com</email>
 </author>

 
 <entry>
   <title>Craftsman Swap - Day 3</title>
   <link href="http://abedra.github.com/2010/01/21/craftsmanswap-day-3.html"/>
   <updated>2010-01-21T00:00:00-08:00</updated>
   <id>http://abedra.github.com/2010/01/21/craftsmanswap-day-3</id>
   <content type="html">&lt;h1 id='craftsman_swap__day_3'&gt;Craftsman Swap - Day 3&lt;/h1&gt;
&lt;p class='meta'&gt;21 Jan 2010&lt;/p&gt;
&lt;p&gt;After a great first couple of days I was really starting to catch a groove at the &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; office. I switched off to a new project and a new pair. The task today was to take a look at integrating Paypal&amp;#8217;s express checkout for an online retail application in Rails. My pair for the day was Nate Jackson. Nate started out at &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; as an apprentice and became a full time employee after his journey was complete. It&amp;#8217;s great to see people who have enjoyed the experience and had such a positive view of their mentorship that they want to continue to work with their mentors. It is also great to see the mentors accept everyone as peers. It might not seem like a big deal, but it makes a huge difference!&lt;/p&gt;

&lt;p&gt;One of the things I love about pairing is sitting down for the first time with somebody and observing how they work. Ruby on Rails gives us a common ground for ideas and communication, but the way we communicate is always different. It&amp;#8217;s fun to see different tools and environments, and to see in what ways people invest in their tools to help make them a more productive programmer. We started out our pairing by firing up &lt;a href='http://www.gnu.org/software/emacs'&gt;the one true editor&lt;/a&gt; and taking a tour of the application to get an idea of what we needed to do to accomplish our goals. The morning seemed to fly by. As soon as we were done walking through the application and reading the PayPal documentation it was time to head to lunch.&lt;/p&gt;

&lt;p&gt;After lunch it was time to get cracking on our task. We were off to a great start with PayPal using the &lt;code&gt;active_merchant&lt;/code&gt; gem. Unfortunately that didn&amp;#8217;t last long. We had setup the basic developer sandbox accounts and got a simple example working, but found out that the proper solution was the &amp;#8220;Pro&amp;#8221; remix. This involved much more setup with the developer sandbox. The nice part is that since the &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; gang works together in the same room, we were able to get the pre-baked account credentials from others that knew where we needed to be. After fighting for a good part of the day around settings in the developer sandbox, and things not working properly, we arrived at what seemed to be a reasonable solution. The bad part was that PayPal just wasn&amp;#8217;t cooperating with us. We were able to confirm that things were working with a live account, just not a developer sandbox account.&lt;/p&gt;

&lt;p&gt;Nate and I were pleasantly suprised at the end of the day by a phone call from Carson Conant over at &lt;a href='http://mediafly.com'&gt;Medifly&lt;/a&gt;. Palm had contacted him to produce an app for the Pre and Pixi that would be able to stream the &amp;#8220;Hope for Haiti&amp;#8221; concert and allow for people to donate directly from their phones. The only downside was that we would only have one day to complete it. &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; had already built the original Pre app for &lt;a href='http://mediafly.com'&gt;Mediafly&lt;/a&gt; so we at least had a base app to work from. I was excited and nervous all at once for what day four would bring.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Craftsman Swap - Day 2</title>
   <link href="http://abedra.github.com/2010/01/20/craftsmanswap-day-2.html"/>
   <updated>2010-01-20T00:00:00-08:00</updated>
   <id>http://abedra.github.com/2010/01/20/craftsmanswap-day-2</id>
   <content type="html">&lt;h1 id='craftsman_swap__day_2'&gt;Craftsman Swap - Day 2&lt;/h1&gt;
&lt;p class='meta'&gt;20 Jan 2010&lt;/p&gt;
&lt;p&gt;Context and situational awareness are a very important key to working well with others, and day two of my journey solidified that idea. The day started off similar to my first day. I was excited to be working with Ryan on &lt;a href='http://madmimi.com'&gt;Mad Mimi&lt;/a&gt; for another day. Having a better understanding of how Ryan works and how things at &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; flow during the day helped me concentrate more on getting real work done. After the morning standup Ryan and I were off to new feature development. We started off by writing tests for importing csv lists of recipients or &amp;#8220;audience members&amp;#8221; for email campaigns. Ryan had already done a lot of the leg work and refactoring, so it was all about tying a bow around things. Ryan and I were into a good pairing groove and the morning seemed to fly by.&lt;/p&gt;

&lt;p&gt;Lunch time brought about a tradition that every company should adopt. &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; calls this tradition &lt;a href='http://twitter.com/geekfest'&gt;Geekfest&lt;/a&gt;, which is a &amp;#8220;lunch and learn&amp;#8221; style gathering where someone gives a talk on something new. I know that a lot of people do this informally, but &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; has made this a regular event and I applaud the effort that can go into to herding a bunch of developers in a room during the work week. I was also surprised to see the actual number of employees that &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; has. If it weren&amp;#8217;t for &lt;a href='http://twitter.com/geekfest'&gt;Geekfest&lt;/a&gt; I probably wouldn&amp;#8217;t have been able to meet all the other developers that work on site during the week. I gave a presentation on &lt;a href='http://compojure.org'&gt;compojure&lt;/a&gt;, a Sinatra like web framework for &lt;a href='http://clojure.org/'&gt;clojure&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The day rounded out with Ryan and I making some UI enhancements and finishing up the feature from the morning. Since the deployment strategy involves multiple servers, keeping the csv lists around for batch processing presented an interesting deployment issue. We wrote out a few ideas for deployment solutions and then got in contact with Rails Machine to get their opinion so we could start prepping for the feature release.&lt;/p&gt;

&lt;p&gt;Since this was my last day pairing with Ryan we ended the day with a retrospective to talk about how our pairing experience went. A few others sat in to offer outside perspectives and chat about initial impressions and what could be better throughout the rest of the week. This was a great way to end the day and pump me up for what&amp;#8217;s to come!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Craftsman Swap - Day 1</title>
   <link href="http://abedra.github.com/2010/01/19/craftsmanswap-day-1.html"/>
   <updated>2010-01-19T00:00:00-08:00</updated>
   <id>http://abedra.github.com/2010/01/19/craftsmanswap-day-1</id>
   <content type="html">&lt;h1 id='craftsman_swap__day_1'&gt;Craftsman Swap - Day 1&lt;/h1&gt;
&lt;p class='meta'&gt;19 Jan 2010&lt;/p&gt;
&lt;p&gt;I started my journey Sunday night to Chicago where I was welcomed into the &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; corporate apartment by &lt;a href='http://www.ethangunderson.com'&gt;Ethan Gunderson&lt;/a&gt;. I was impressed by the layout and attention to design. It is a swank little downtown pad that anyone would be happy to have. &lt;a href='http://www.ethangunderson.com'&gt;Ethan&lt;/a&gt; is one of &lt;a href='http://obtiva.com'&gt;Obtiva&amp;#8217;s&lt;/a&gt; apprentices, working for 6 months at &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; where he contributes to the team and sharpens his skills as a developer. I really like this idea and would love to see more companies making good developers great.&lt;/p&gt;

&lt;p&gt;Monday reminded me of the things I love about being in a big city. The walk to the office in the wonderful Chicago weather made for a nice wake up. The morning started out much like other good agile shops i&amp;#8217;ve been to with a morning stand up meeting. A lot of the &lt;a href='http://obtiva.com'&gt;Obtiva&lt;/a&gt; are on site at clients so the meeting was very short. I noticed that after the company wide standup other teams of people had more focused standups which is a great idea. It let&amp;#8217;s the group get to work while details are discussed among the relevant parties.&lt;/p&gt;

&lt;p&gt;For my first day I got to pair with &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan Briones&lt;/a&gt;. I know &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan&lt;/a&gt; from my days in Columbus OH, so it was nice to start my week of with a familiar face. We started with a brief discussion about the project, Mad Mimi, which is an email marketing system. &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan&lt;/a&gt; had plans laid out for the days work, but as things go we were able to defeat those plans and work on an entirely different set of problems.&lt;/p&gt;

&lt;p&gt;We spent the first part of our day working on a little bit of housekeeping and deployment related issues. It was nice to see the server setup and hosting company choices. I also got to see the response and support from Rails Machine first hand as one of our deployments failed. Within a couple of minutes they were on top of everything before anyone could even ask. This kind of reaction to a problem combined with great support staff which they seem to have make for a great hosting experience.&lt;/p&gt;

&lt;p&gt;After a great burger at lunch &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan&lt;/a&gt; and I jumped back into things and were greeted with an interesting problem. A company was trying to start an email campaign with a record breaking amount of emails. Things weren&amp;#8217;t going quite to plan and it was up to &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan&lt;/a&gt; and I (with some help from &lt;a href='http://redsquirrel.com/dave'&gt;Dave Hoover&lt;/a&gt;) to track down and fix the problem. After some debugging and extra logging (it&amp;#8217;s like cowbell, you always need more), we were able to make some modifications and get the process moving. There are still a few performance tweaks to make, but history was made.&lt;/p&gt;

&lt;p&gt;Once things were moving along nicely we moved into some other bug fixes to round out the day. We got to sit down this time and write some tests that proved our bug (and a couple other bugs that weren&amp;#8217;t immediately apparent) and get to work. We were able to end the day by getting the bug squashed and watching the record breaking email campaign start it&amp;#8217;s mailings.&lt;/p&gt;

&lt;p&gt;The evening brought good food and good company as I went to dinner with &lt;a href='http://brionesandco.com/ryanbriones'&gt;Ryan&lt;/a&gt;, &lt;a href='http://www.ethangunderson.com'&gt;Ethan&lt;/a&gt;, and Ryan&amp;#8217;s wife Stephanie. We ate some sushi down by Ryan&amp;#8217;s house at a place called Ra. We ended the night with some coffee and good conversation that I hope will continue throughout the rest of the week.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Craftsman Swap</title>
   <link href="http://abedra.github.com/2010/01/17/craftsman-swap.html"/>
   <updated>2010-01-17T00:00:00-08:00</updated>
   <id>http://abedra.github.com/2010/01/17/craftsman-swap</id>
   <content type="html">&lt;h1 id='craftsman_swap'&gt;Craftsman Swap&lt;/h1&gt;
&lt;p class='meta'&gt;17 Jan 2010&lt;/p&gt;
&lt;p&gt;I am headed to Chicago this week to work at &lt;span&gt;Obtiva&lt;/span&gt; for the first of what I hope will be many craftsman swaps. I am really looking forward to hanging out with the crew up there and learning how other top notch development companies work. I will be keeping notes of my experiences while I am up there and will report a few times during the week.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tell RCov to Cov Off</title>
   <link href="http://abedra.github.com/2009/10/16/nocov.html"/>
   <updated>2009-10-16T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/10/16/nocov</id>
   <content type="html">&lt;h1 id='tell_rcov_to_cov_off'&gt;Tell RCov to Cov Off&lt;/h1&gt;
&lt;p class='meta'&gt;16 Oct 2009&lt;/p&gt;
&lt;p&gt;&lt;a href='http://spicycode.com'&gt;Chad&lt;/a&gt; and I just released a new version of &lt;a href='http://github.com/relevance/rcov'&gt;RCov&lt;/a&gt;! This version offers the ability to tell RCov to ignore certain pieces of code. This is useful if you are experiencing an bug in RCov, or if you just plain old disagree with RCov about the coverage status of a particular chunk of code. Here&amp;#8217;s an example of implementation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Foo
  def bar
    1 + 2
  end

  #:nocov:
  def quux
    &amp;quot;s&amp;quot; + &amp;quot;hit&amp;quot;
  end
  #:nocov:

end

require &amp;#39;test/unit&amp;#39;
class FooTest &amp;lt; Test::Unit::TestCase
  def test_bar
    assert_equal 3, Foo.new.bar
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Running this will show you 100% code coverage. This feature (for now) is pretty simple and does not do anything more than tell RCov to count the code as covered. If this feature takes off, I will spend more time making it smarter about the code and reporting so that you can easily tell the difference.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RCov Examples</title>
   <link href="http://abedra.github.com/2009/08/14/rcov-examples.html"/>
   <updated>2009-08-14T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/08/14/rcov-examples</id>
   <content type="html">&lt;h1 id='rcov_examples'&gt;RCov Examples&lt;/h1&gt;
&lt;p class='meta'&gt;14 Aug 2009&lt;/p&gt;
&lt;p&gt;Are you interested in trying out &lt;a href='http://github.com/relevance/rcov'&gt;RCov&lt;/a&gt;? Are you unsure of how to start? Are you looking to improve the RCov-fu on your project? I have just the solution for you! I have started &lt;a href='http://github.com/abedra/rcov-examples'&gt;a project&lt;/a&gt; that demonstrates different RCov configurations for different testing frameworks. This project is meant to help spread RCov related knowledge. You can get the bits by running:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git clone git://github.com/abedra/rcov-examples.git&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Feel free to browse around and submit any feedback. I am hoping to get as many samples in as possible, so feel free to contribute!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Getting Started With Compojure</title>
   <link href="http://abedra.github.com/2009/08/11/getting-started-with-compojre.html"/>
   <updated>2009-08-11T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/08/11/getting-started-with-compojre</id>
   <content type="html">&lt;h1 id='getting_started_with_compojure'&gt;Getting Started With Compojure&lt;/h1&gt;
&lt;p class='meta'&gt;11 Aug 2009&lt;/p&gt;
&lt;p&gt;&lt;a href='http://github.com/weavejester/compojure'&gt;Compojure&lt;/a&gt; is a great web framework written in &lt;a href='http://github.com/richhickey/clojure'&gt;Clojure&lt;/a&gt;. Although in its infancy, the project has a lot of promise. The best part is that getting started is a snap!&lt;/p&gt;

&lt;p&gt;The only thing you need to have installed on your system is Java and Ant. Everything else is taken care of for you by Compojure. To make things even simpler I have &lt;a href='/assets/compojure'&gt;provided a script&lt;/a&gt; that does all of the project setup for you. Let&amp;#8217;s take a look.&lt;/p&gt;

&lt;p&gt;After you have downloaded the script, make sure to make it executable (&lt;code&gt;chmod +x compojure&lt;/code&gt;) then run it:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;compojure &amp;lt;project name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;where project name is whatever you want it to be. The script will download Compojure and it&amp;#8217;s dependencies, do a fresh build, and copy all of the necessary dependencies for your project into the directory you specified. It will then leave you with a &lt;code&gt;&amp;lt;project name&amp;gt;.clj&lt;/code&gt; file that has a &amp;#8220;Hello World&amp;#8221; example built right in. When the script finishes running just run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;./start&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;and go to &lt;code&gt;http://localhost:8080&lt;/code&gt;. You are now up and running on Compojure! To get a better idea of how to work with Compojure you can check out &lt;a href='http://en.wikibooks.org/wiki/Compojure'&gt;this site&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Failing Your Builds with RCov</title>
   <link href="http://abedra.github.com/2009/08/07/fail-your-builds-with-rcov.html"/>
   <updated>2009-08-07T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/08/07/fail-your-builds-with-rcov</id>
   <content type="html">&lt;h1 id='failing_your_builds_with_rcov'&gt;Failing Your Builds with RCov&lt;/h1&gt;
&lt;p class='meta'&gt;07 Aug 2009&lt;/p&gt;
&lt;p&gt;I just pushed the latest bits to &lt;a href='&amp;quot;http://github.com/relevance/rcov&amp;quot;'&gt;RCov&lt;/a&gt;, and they include a new option to help you fail in more spectacular ways! Have you ever made sure that your build fails if you don&amp;#8217;t satisfy the coverage threshold? If you are in &lt;a href='http://github.com/dchelimsky/rspec'&gt;RSpec&lt;/a&gt; land, you have always been able to use the built in &lt;code&gt;verify_rcov&lt;/code&gt; task, but if you are using any of the other testing frameworks, it has historically been quite a process.&lt;/p&gt;

&lt;p&gt;To use the new hotness, simply add &lt;code&gt;--failure-threshold xx&lt;/code&gt; where &lt;code&gt;xx&lt;/code&gt; is the threshold you want your coverage to be at. If your coverage drops below that threshold you will get a message telling you, but more importantly your build will &lt;em&gt;actually&lt;/em&gt; fail. RCov exits non-zero when you fail to satisfy the coverage threshold which means that your Continuous Integration builds will fail. Having this in your bag of tricks is an awesome thing, and can help ensure that everyone is checking in tests along with their code.&lt;/p&gt;

&lt;p&gt;To get the latest RCov bits simply run:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;gem install relevance-rcov -s http://gems.github.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You should get at least version 0.8.5. The &lt;code&gt;--failure-threshold&lt;/code&gt; option will be included in RCov 0.8.5 and higher. As always, if you have any issues please report them to the &lt;a href='&amp;quot;http://github.com/relevance/rcov/issues&amp;quot;'&gt;RCov issue tracker&lt;/a&gt; and I will be sure to take a look. If you are going to submit a bug, check out this &lt;a href='&amp;quot;http://blog.thinkrelevance.com/2009/7/28/rcov-bug-reporting&amp;quot;'&gt;tasty groove&lt;/a&gt; that will give you some tips on how to properly submit a bug report for RCov. Enjoy your Whales!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>RubyNation Wrapup</title>
   <link href="http://abedra.github.com/2009/06/13/rubynation-wrapup.html"/>
   <updated>2009-06-13T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/06/13/rubynation-wrapup</id>
   <content type="html">&lt;h1 id='rubynation_wrapup'&gt;RubyNation Wrapup&lt;/h1&gt;
&lt;p class='meta'&gt;13 Jun 2009&lt;/p&gt;
&lt;p&gt;&lt;a href='&amp;quot;http://rubynation.org&amp;quot;'&gt;RubyNation&lt;/a&gt; has been a very nice conference. The quality of talks was excellent as well as the crowd. I got a chance to meet some very cool people and even talk a little bit of &lt;a href='&amp;quot;http://clojure.org&amp;quot;'&gt;Clojure&lt;/a&gt;. The slides for my talk on RCov and Ruby 1.9 can be found &lt;a href='&amp;quot;http://aaronbedra.com/assets/rcov19-rn.pdf&amp;quot;'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Getting RunCodeRun Build Status for a Specific Project</title>
   <link href="http://abedra.github.com/2009/06/05/getting-rcr-status-for-a-specific-project.html"/>
   <updated>2009-06-05T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/06/05/getting-rcr-status-for-a-specific-project</id>
   <content type="html">&lt;h1 id='getting_runcoderun_build_status_for_a_specific_project'&gt;Getting RunCodeRun Build Status for a Specific Project&lt;/h1&gt;
&lt;p class='meta'&gt;05 Jun 2009&lt;/p&gt;
&lt;p&gt;Are you on &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; yet? If not, stop, go to &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; and signup! Now that you have the awesome sauce I am going to show you how to display &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; build statuses for individual projects anywhere on your website. Earlier this year &lt;a href='http://www.vanderburg.org/Blog'&gt;Glenn Vanderburg&lt;/a&gt; created the &lt;a href='http://thinkrelevance.rubyforge.org/runcoderun_badge/'&gt;RunCodeRun Badge Project&lt;/a&gt; that allows you to display your &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; build statues on any website. This project is very cool and gives you a nice piece of art for your site. This project is a modification of &lt;a href='http://drnicjavascript.rubyforge.org/github_badge/'&gt;Dr. Nic&amp;#8217;s Github Badge Project&lt;/a&gt;. The focus of this article is to arm you with the codez to have individual control over where and how you display &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; build statuses. If you look at the landing page for my blog you will notice that I have this hotness already implemented.&lt;/p&gt;

&lt;p&gt;&lt;img src='/assets/rcr-example.jpg' alt='home' /&gt;&lt;/p&gt;

&lt;p&gt;It turns out that this is incredibly simple to do. Let&amp;#8217;s take a look at the basics&amp;#8230;&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getScript&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;http://runcoderun.com/api/v1/json/abedra?callback=parseData&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This starts all the magic. It calls out to the &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; API and returns a JSON payload with all the open source build statuses linked to your account. Let&amp;#8217;s break this down quick. &lt;code&gt;$.getScript()&lt;/code&gt; is a &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt; &lt;a href='http://docs.jquery.com/Ajax/jQuery.getScript'&gt;function&lt;/a&gt; that allows you to do an Ajax request to a different domain than the one your site is currently running on. This is important because what you are essentially doing is a &lt;a href='http://www.owasp.org/index.php/Cross_site_scripting'&gt;Cross Site Scripting&lt;/a&gt; exploit on your own site. This, however, is acceptable to do if you know what is actually happening. The reason a standard &lt;a href='http://jquery.com/'&gt;jQuery&lt;/a&gt; &lt;code&gt;$.get&lt;/code&gt; won&amp;#8217;t work is because it violates &lt;a href='http://en.wikipedia.org/wiki/Same_origin_policy'&gt;Javascript&amp;#8217;s same origin policy&lt;/a&gt; constraints. The next thing to break down here is the &lt;code&gt;?callback=parseData&lt;/code&gt; at the end of the request. This is done so that the data we get back from the &lt;code&gt;$.getScript()&lt;/code&gt; call can be processed. Under the covers the &lt;code&gt;parseData()&lt;/code&gt; function looks like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;parseData&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;castronaut&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;user&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;projects&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;rcov&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;user&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;projects&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;safe_erb&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;user&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;projects&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;mpi_ruby&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;data&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;user&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;projects&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;];&lt;/span&gt;

  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;#rcov&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;generateStatus&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;rcov&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;#castronaut&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;generateStatus&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;castronaut&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;#mpi-ruby&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;generateStatus&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;mpi_ruby&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
  &lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;#safe-erb&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;append&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;generateStatus&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;safe_erb&lt;/span&gt;&lt;span class='p'&gt;));&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;A user object is returned to you that contains an array of projects. For now, the &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; API does not have a named key for each project, so you have to use the appropriate array index for each project in order to get the details. &lt;code&gt;parseData()&lt;/code&gt; calls the &lt;code&gt;generateStatus()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;span class='kd'&gt;function&lt;/span&gt; &lt;span class='nx'&gt;generateStatus&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;status&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;success&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;lt;span class=&amp;#39;success&amp;#39;&amp;gt; succeeded &amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;lt;span&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;prettyDate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;ended_at&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;lt;a href=&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;gt;details&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='k'&gt;else&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;lt;span class=&amp;#39;failure&amp;#39;&amp;gt; failed &amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;lt;span&amp;gt;&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;prettyDate&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;ended_at&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot; &amp;lt;a href=&amp;quot;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='nx'&gt;project&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;url&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;gt;details&amp;lt;/a&amp;gt;&amp;lt;/span&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
&lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;generateStatus()&lt;/code&gt; then calls &lt;code&gt;prettyDate()&lt;/code&gt;. This is a small &lt;a href='http://ejohn.org/blog/javascript-pretty-date'&gt;library&lt;/a&gt; written by &lt;a href='http://ejohn.org/blog/'&gt;John Resig&lt;/a&gt;. I had to make a small patch to get it to work with the dates that the &lt;a href='http://runcoderun.com'&gt;RunCodeRun&lt;/a&gt; API sends back. The patched version can be found &lt;a href='http://www.aaronbedra.com/javascripts/pretty.js'&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id='takeaway'&gt;Takeaway&lt;/h2&gt;

&lt;p&gt;The full implementation exists in the source of this site at &lt;a href='http://github.com/abedra/abedra.github.com'&gt;http://github.com/abedra/abedra.github.com&lt;/a&gt;. If you just want something simple to display the status of all your builds use the &lt;a href='http://thinkrelevance.rubyforge.org/runcoderun_badge/'&gt;RunCodeRun Badge Project&lt;/a&gt;. If you want a little more control over what is displayed this should get you off to a good start.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>DC Developer Day Wrapup</title>
   <link href="http://abedra.github.com/2009/05/30/developer-day-wrapup.html"/>
   <updated>2009-05-30T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/05/30/developer-day-wrapup</id>
   <content type="html">&lt;h1 id='dc_developer_day_wrapup'&gt;DC Developer Day Wrapup&lt;/h1&gt;
&lt;p class='meta'&gt;30 May 2009&lt;/p&gt;
&lt;p&gt;The &lt;a href='http://developer-day.com' title='Developer Day'&gt;DC Developer Day&lt;/a&gt; was a hit! There were a lot of good talks and interesting people. For a closer look at the events that transpired you can search twitter for #devdaydc. You can find my slides on RCov and the Ruby 1.9 changes &lt;a href='http://aaronbedra.com/assets/rcov19.pdf'&gt;here&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Castronaut Updates - Version 0.7.5 Released</title>
   <link href="http://abedra.github.com/2009/05/22/castronaut-updates.html"/>
   <updated>2009-05-22T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/05/22/castronaut-updates</id>
   <content type="html">&lt;h1 id='castronaut_updates__version_075_released'&gt;Castronaut Updates - Version 0.7.5 Released&lt;/h1&gt;
&lt;p class='meta'&gt;22 May 2009&lt;/p&gt;
&lt;p&gt;&lt;a href='http://github.com/relevance/castronaut' title='Castronaut'&gt;Castronaut&lt;/a&gt; has had some much needed lovin applied to it. I have updated the test suite to work with the latest version of &lt;a href='http://github.com/dchelimsky/rspec/tree/master' title='RSpec'&gt;RSpec&lt;/a&gt;. The test suite is happy again and all of the deprication warnings left over from the &lt;a href='http://www.sinatrarb.com/' title='Sinatra'&gt;Sinatra&lt;/a&gt; upgrade are now resolved. The gemspec has been cleaned to remove some unnecessary files and an &lt;a href='http://github.com/relevance/castronaut/issues/closed#issue/2' title='XSS bug'&gt;XSS bug&lt;/a&gt; has been fixed that was present on the login page. Just a reminder that issue tracking has been switched to &lt;a href='http://github.com/blog/411-github-issue-tracker' title='Github Issues'&gt;Github Issues&lt;/a&gt;, so if you encounter any problems please post them over at &lt;a href='http://github.com/relevance/castronaut/issues' title='http://github.com/relevance/castronaut/issues'&gt;http://github.com/relevance/castronaut/issues&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Central Ohio ISSA Information Security Summit Wrapup</title>
   <link href="http://abedra.github.com/2009/05/16/infosec-summit-wrapup.html"/>
   <updated>2009-05-16T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/05/16/infosec-summit-wrapup</id>
   <content type="html">&lt;h1 id='central_ohio_issa_information_security_summit_wrapup'&gt;Central Ohio ISSA Information Security Summit Wrapup&lt;/h1&gt;
&lt;p class='meta'&gt;16 May 2009&lt;/p&gt;
&lt;p&gt;The &lt;a href='http://infosecsummit.org' title='Infosec Summit'&gt;Infosec Summit&lt;/a&gt; was a great success! There were a lot of great talks, and some pretty cool demonstrations. I am happy to have been a part of it and hope to head back next year. If you missed it, you should definitely put it on your conference watch list. Slides from my talk can be found &lt;a href='http://abedra.github.com/assets/auditing-code.pdf' title='Auditing Code'&gt;HERE&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Laziness, I Haz It</title>
   <link href="http://abedra.github.com/2009/04/23/laziness-i-haz-it.html"/>
   <updated>2009-04-23T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2009/04/23/laziness-i-haz-it</id>
   <content type="html">&lt;h1 id='laziness_i_haz_it'&gt;Laziness, I Haz It&lt;/h1&gt;
&lt;p class='meta'&gt;23 Apr 2009&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s been a while since I posted anything at all. I apologize for all the radio silence, and hope to do better from now on. In all of my laziness over the past few months I decided to move by blog over to github and take the github pages way out. This is going to make things much simpler to manage, since I use the incredibly awesome &lt;a href='http://github.com' title='Github'&gt;Github&lt;/a&gt; to manage my code I thought it would be best just to keep things all in the same place.&lt;/p&gt;

&lt;p&gt;I do have some cool new stuff in the works, so stay tuned for updates on my recent talks, ideas, and open source projects.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Tarantula 0.0.8.1 Released</title>
   <link href="http://abedra.github.com/2009/01/16/tarantula-0-0-8-1-released.html"/>
   <updated>2009-01-16T00:00:00-08:00</updated>
   <id>http://abedra.github.com/2009/01/16/tarantula-0-0-8-1-released</id>
   <content type="html">&lt;h1 id='tarantula_0081_released'&gt;Tarantula 0.0.8.1 Released&lt;/h1&gt;
&lt;p class='meta'&gt;16 Jan 2009&lt;/p&gt;
&lt;p&gt;&lt;a href='http://jasonrudolph.com/' title='Jason'&gt;Jason&lt;/a&gt; did some great work today testing and cleaning up some of the rough edges with &lt;a href='http://github.com/relevance/tarantula' title='Tarantula'&gt;Tarantula&lt;/a&gt;. A new version has been released and it&amp;#8217;s now getting ever so close to hitting 1.0. You can install the gem from github via&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;% gem install relevance-tarantula --source http://gems.github.com
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;As always, if you find any bugs or are having trouble with &lt;a href='http://github.com/relevance/tarantula' title='Tarantula'&gt;Tarantula&lt;/a&gt; you can report them at the &lt;a href='http://relevance.lighthouseapp.com/projects/17868-tarantula/overview' title='Tarantula Lighthouse'&gt;Tarantula Lighthouse&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Stop. Emacs Time.</title>
   <link href="http://abedra.github.com/2008/10/03/stop-emacs-time.html"/>
   <updated>2008-10-03T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/10/03/stop-emacs-time</id>
   <content type="html">&lt;h1 id='stop_emacs_time'&gt;Stop. Emacs Time.&lt;/h1&gt;
&lt;p class='meta'&gt;03 Oct 2008&lt;/p&gt;
&lt;p&gt;I decided to get all crazy and re-theme my blog based on my favorite editor. It&amp;#8217;s still got a couple of rough edges, but it&amp;#8217;s coming along. Please comment with any strangeness.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Windy City Rails Wrap-up</title>
   <link href="http://abedra.github.com/2008/09/23/windy-city-rails-wrap-up.html"/>
   <updated>2008-09-23T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/09/23/windy-city-rails-wrap-up</id>
   <content type="html">&lt;h1 id='windy_city_rails_wrapup'&gt;Windy City Rails Wrap-up&lt;/h1&gt;
&lt;p class='meta'&gt;23 Sep 2008&lt;/p&gt;
&lt;p&gt;Saturday&amp;#8217;s Windy City Rails event was great! There were some great talks and good conversation. I would like to thank &lt;a href='http://chicagoruby.org' title='Chicago Ruby'&gt;Chicago Ruby&lt;/a&gt; along with the conference organizers who made all of this possible.&lt;/p&gt;

&lt;p&gt;You can download slides for my &lt;a href='/assets/windycityrails-sleight-of-hand.pdf' title='sleight of hand'&gt;Sleight of Hand&lt;/a&gt; and my &lt;a href='/assets/windycityrails-security.pdf' title='security'&gt;Security&lt;/a&gt; talk in the previous links.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Speaking at Windy City Rails</title>
   <link href="http://abedra.github.com/2008/08/20/i-m-speaking-at-windy-city-rails.html"/>
   <updated>2008-08-20T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/08/20/i-m-speaking-at-windy-city-rails</id>
   <content type="html">&lt;h1 id='speaking_at_windy_city_rails'&gt;Speaking at Windy City Rails&lt;/h1&gt;
&lt;p class='meta'&gt;20 Aug 2008&lt;/p&gt;
&lt;p&gt;I just got word from the tribal council at the &lt;a href='http://windycityrails.org/' title='Windy City Rails'&gt;Windy City Rails&lt;/a&gt; conference that they have accepted two of my proposals. I will be giving my RailsConf 2008 talk &amp;#8220;De-Railing: Smashing the Rails Stack&amp;#8221; along with &amp;#8220;Sleight of Hand for the Ruby Man&amp;#8221;. The De-Railing talk is a security focused session on steps to take to ensure that your Rails application has what it needs to keep data safe from attackers. The Sleight of Hand talk is a session on metaprogramming tips, tricks, and pitfalls with Ruby and with Rails. Stay tuned for more info closer to the September 20th conference date.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Adventures in Clojure - Getting Started</title>
   <link href="http://abedra.github.com/2008/08/17/adventures-in-clojure-getting-started.html"/>
   <updated>2008-08-17T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/08/17/adventures-in-clojure-getting-started</id>
   <content type="html">&lt;h1 id='adventures_in_clojure__getting_started'&gt;Adventures in Clojure - Getting Started&lt;/h1&gt;
&lt;p class='meta'&gt;17 Aug 2008&lt;/p&gt;
&lt;p&gt;Following &lt;a href='http://blog.thinkrelevance.com/2008/8/12/java-next-2-java-interop' title='Stu&amp;apos;s series on Java.next'&gt;Stu&amp;#8217;s series on Java.next&lt;/a&gt; I decided to take a look into &lt;a href='http://clojure.org' title='clojure'&gt;Clojure&lt;/a&gt;. Clojure is a pretty cool language. It&amp;#8217;s a lisp dialect that runs on the JVM. This is cool for a couple of reasons. First, you get all the advantages of the jvm. Second, you get the advantage of interoperability with java libraries. I am not necessarily excited about the later, nonetheless, there are still advantages to having solutions to problems that you can use to quickly get things done.&lt;/p&gt;

&lt;p&gt;Although clojure has a nice website with decent language descriptions and a helpful &lt;a href='http://en.wikibooks.org/wiki/Clojure_Programming' title='wiki'&gt;Wiki&lt;/a&gt;, getting started can leave you a little wanting. Here&amp;#8217;s a more precise setup guide to get you going. I am using Ubuntu Hardy on my desktop PC so this guide will be geared towards it.&lt;/p&gt;

&lt;p&gt;First, let&amp;#8217;s install the necessary base libraries&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% sudo apt-get install sun-java6-jdk maven2 subversion&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now let&amp;#8217;s check out the clojure source and build it&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% svn co https://clojure.svn.sourceforge.net/svnroot/clojure/trunk clojure
% cd clojure
% mvn install&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When maven gets finished you should end up with a shiny new jar in the target dir of the clojure source directory. Now to test this out let&amp;#8217;s try the following from inside the clojure directory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% java -cp target/clojure-lang-1.0-SNAPSHOT.jar clojure.lang.Repl
Clojure
user=&amp;gt; &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now that we have the basics setup we need to get our environment setup for real programming. The first enhancements come to the repl. It would be nice to have command completion, parenthesis matching (this is lisp after all), history across sessions, and last but not least editor hooks. The wiki suggests both JLine and rlwrap. JLine is ok, but lacking in the ability to do command completion and some other goodies. That being said let&amp;#8217;s install rlwrap so that we get the most out of our environment.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% sudo apt-get install rlwrap&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Next we need to create a script to make launching the clojure environment a little bit easier. Here&amp;#8217;a a script from the wiki to help us out.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#!/bin/bash
BREAK_CHARS=&amp;quot;(){}[],^%$#@\&amp;quot;\&amp;quot;;:&amp;#39;&amp;#39;|\\&amp;quot;
CLOJURE_DIR=/usr/local/clojure
CLOJURE_JAR=$CLOJURE_DIR/target/clojure-lang-1.0-SNAPSHOT.jar
if [ -z &amp;quot;$1&amp;quot; ]; then
    rlwrap --remember -c -b $BREAK_CHARS -f /home/abedra/.clj_completions \
        java -cp $CLOJURE_JAR clojure.lang.Repl
else
    java -cp $CLOJURE_JAR clojure.lang.Script $1
fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;As you can see I moved the clojure directory to &lt;code&gt;/usr/local/&lt;/code&gt;. I also had to modify the path to the &lt;code&gt;.clj_completions file&lt;/code&gt;. Just copy this script, save it, &lt;code&gt;chmod +x&lt;/code&gt;, and move it to &lt;code&gt;/usr/local/bin/&lt;/code&gt;. Make sure you properly modify the paths. Last, just go ahead a create an empty file at &lt;code&gt;~/.clj_completions&lt;/code&gt;. We will populate that next. Let&amp;#8217;s use this script to populate the &lt;code&gt;.clj_completions&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;(defmacro with-out-file [pathname &amp;amp; body]
  `(with-open stream# (new java.io.FileWriter ~pathname)
     (binding [*out* stream#]
       ~@body)))

(def completions (keys (ns-publics (find-ns &amp;#39;clojure))))
(with-out-file &amp;quot;clj-keys.txt&amp;quot; (doseq x completions (println x)))&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Save this code as &lt;code&gt;clj-completions.clj&lt;/code&gt;. Now simply run the script.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% clj clj-completions.clj&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once it&amp;#8217;s finished you&amp;#8217;ll end up with a file named clj-keys.txt. Simply move that file to &lt;code&gt;~/.clj_completions&lt;/code&gt; and you are ready to rock. Now let&amp;#8217;s test out our new hotness. Once you invoke clj try typing in some code and pressing tab.&lt;/p&gt;

&lt;p&gt;Now you are ready to get programming! Stay tuned for more adventures in clojure.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Upgrades</title>
   <link href="http://abedra.github.com/2008/07/09/upgrades.html"/>
   <updated>2008-07-09T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/07/09/upgrades</id>
   <content type="html">&lt;h1 id='upgrades'&gt;Upgrades&lt;/h1&gt;
&lt;p class='meta'&gt;09 Jul 2008&lt;/p&gt;
&lt;p&gt;I just updated to the current git master version of mephisto. I was running an old version of 7.3, so if anything is out of whack please shoot me a message and let me know. I am working on getting the syntax highlighting working again, it was suffering from some boundary issues.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Sleight of Hand for the Ruby Man</title>
   <link href="http://abedra.github.com/2008/06/12/slight-of-hand-for-the-ruby-man.html"/>
   <updated>2008-06-12T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/06/12/slight-of-hand-for-the-ruby-man</id>
   <content type="html">&lt;h1 id='sleight_of_hand_for_the_ruby_man'&gt;Sleight of Hand for the Ruby Man&lt;/h1&gt;
&lt;p class='meta'&gt;12 Jun 2008&lt;/p&gt;
&lt;p&gt;&lt;a href='http://spicycode.com' title='Chad Humphries'&gt;Chad Humphries&lt;/a&gt; pointed me to &lt;a href='http://programmingishard.com/code/507' title='this'&gt;this&lt;/a&gt; tasty bit of code. Since Ruby so graciously lets you open up classes anywhere, it&amp;#8217;s nice to know where the right place to debug is. Simply put the following code into a globally accessible place (I just used .irbrc) and you will have the method available.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Kernel&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;where_is_this_defined&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;settings&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='p'&gt;{},&lt;/span&gt; &lt;span class='o'&gt;&amp;amp;&lt;/span&gt;&lt;span class='n'&gt;block&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;settings&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:debug&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;
    &lt;span class='n'&gt;settings&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:educated_guess&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt;

    &lt;span class='n'&gt;events&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt;

    &lt;span class='nb'&gt;set_trace_func&lt;/span&gt; &lt;span class='nb'&gt;lambda&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;binding&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;classname&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
    &lt;span class='n'&gt;events&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:event&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:file&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:line&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:binding&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nb'&gt;binding&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:classname&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;classname&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
 
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;settings&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:debug&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;event =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;file =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;line =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;id =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;binding =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;binding&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;classname =&amp;gt; &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;classname&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
      &lt;span class='nb'&gt;puts&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;&amp;#39;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt; 
    &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='k'&gt;yield&lt;/span&gt;
    &lt;span class='nb'&gt;set_trace_func&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kp'&gt;nil&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

    &lt;span class='n'&gt;events&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='k'&gt;next&lt;/span&gt; &lt;span class='k'&gt;unless&lt;/span&gt; &lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:event&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;call&amp;#39;&lt;/span&gt; &lt;span class='ow'&gt;or&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:event&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;return&amp;#39;&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:classname&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;included_modules&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;include?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Associations&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:classname&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; received message &amp;#39;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;, Line &lt;/span&gt;&lt;span class='se'&gt;\#&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:line&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; of &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:file&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;settings&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:educated_guess&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='ow'&gt;and&lt;/span&gt; &lt;span class='n'&gt;events&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;size&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt;
      &lt;span class='n'&gt;event&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;events&lt;/span&gt;&lt;span class='o'&gt;[-&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:classname&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; received message &amp;#39;&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;#39;, Line &lt;/span&gt;&lt;span class='se'&gt;\#&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:line&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt; of &lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;event&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:file&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Unable to determine where method was defined.&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Once you have that you can simply open up script/console or irb and give it a whirl&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='sh'&gt;&amp;gt;&amp;gt; where_is_this_defined &lt;span class='o'&gt;{&lt;/span&gt;Streamlined.ui_for&lt;span class='o'&gt;(&lt;/span&gt;:foo&lt;span class='o'&gt;)}&lt;/span&gt;
&lt;span class='o'&gt;=&lt;/span&gt;&amp;gt; &lt;span class='s2'&gt;&amp;quot;Streamlined received message &amp;#39;ui_for&amp;#39;, Line #6 of /Users/abedra/src/someapp/trunk/lib/extensions/streamlined/streamlined.rb&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This tells us that the &lt;code&gt;ui_for&lt;/code&gt; method of streamlined is actually being called from an extension that the project made rather than the streamlined plugin itself. This would save you lots of time trying to debug the wrong method! Give it a try.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Rails on OpenBSD 4.3</title>
   <link href="http://abedra.github.com/2008/06/07/rails-on-openbsd4-3.html"/>
   <updated>2008-06-07T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/06/07/rails-on-openbsd4-3</id>
   <content type="html">&lt;h1 id='rails_on_openbsd_43'&gt;Rails on OpenBSD 4.3&lt;/h1&gt;
&lt;p class='meta'&gt;07 Jun 2008&lt;/p&gt;
&lt;p&gt;OpenBSD released version 4.3 of their OS on May first. This version is especially exciting because there has been considerable effort made by the ports contributors to get the Rails stack up to date. I will run through a full stack setup from a scratch install. If you need information on installing OpenBSD there is a &lt;a href='http://www.openbsd101.com/installation.html' title='great tutorial'&gt;great tutorial&lt;/a&gt; that will get you started.&lt;/p&gt;

&lt;h2 id='post_install'&gt;Post Install&lt;/h2&gt;

&lt;p&gt;You will be greeted with a vanilla install and not a whole lot to work with. Let&amp;#8217;s get some basic sytem tools installed. We will use OpenBSD&amp;#8217;s &lt;code&gt;pkg_add&lt;/code&gt; tool to get us up and running quickly. The stack we will setup will include helpful system tools, Ruby / Rails, Thin, MySQL, and nginx.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Helpful System Tools&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# build the locate database
% /usr/libexec/locate.updatedb
# setup pkg_add path for easy installs
% export PKG_PATH=ftp://ftp.openbsd.org/pub/OpenBSD/4.3/packages/i386/
# install bash (optional)
% pkg_add -i bash
% chsh -s bash
# install other needed system tools.  we use pkg_add with the -i
# flag for interactive mode.  this way it will ask you what version
# of a specific software you want if there is more than one available.
% pkg_add -i curl nano subversion git&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Ruby / Rails / Thin&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% pkg_add -i ruby ruby-iconv ruby-gems
% gem update --system
% gem install rails thin
# if you want to use thin with sockets you will need to install
# eventmachine from source to get version 0.11
% gem install eventmachine --source http://code.macournoyer.com&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;MySQL&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% pkg_add -i mysql-server
% mysql_install_db
# start mysql
% mysqld_safe &amp;amp;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the file &lt;em&gt;/etc/rc.conf.local&lt;/em&gt; and place the following into it.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;mysql=&amp;quot;YES&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now open up &lt;em&gt;/etc/rc.local&lt;/em&gt; and add the following script just before the ending &lt;em&gt;echo &amp;#8221;.&amp;#8221;&lt;/em&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if [ X&amp;quot;${mysql}&amp;quot; == X&amp;quot;YES&amp;quot; -a -x /usr/local/bin/mysqld_safe ]; then

    echo -n &amp;quot; mysqld&amp;quot;; /usr/local/bin/mysqld_safe --user=_mysql --log --open-files-limit=256 &amp;amp;

    for i in 1 2 3 4 5 6; do
        if [ -S /var/run/mysql/mysql.sock ]; then
            break
        else
            sleep 1
            echo -n &amp;quot;.&amp;quot;
        fi
    done
fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will setup mysql to start when the system boots.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;nginx&lt;/strong&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% pkg_add -i nginx&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then open up &lt;em&gt;/etc/rc.local&lt;/em&gt; and add the following after your mysql entry.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;if [ -x /usr/local/sbin/nginx ]; then
   echo -n &amp;#39; nginx&amp;#39;; /usr/local/sbin/nginx
fi&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will setup nginx to start when the system boots. I like to modify my nginx configs a little bit taking a little away from the debian linux apache2 and nginx configs.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% cd /etc/nginx
% mv nginx.conf nginx.conf.orig
% mkdir sites-available
% mkdir sites-enabled
% curl -O http://aaronbedra.com/nginx.conf
% cd sites-available
% curl -O http://aaronbedra.com/vhost&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will enable nginx to automagically load any vhost file that is in sites-enabled. We use the sites-available and sites-enabled directories and symlink from one to another. I prefer this, you don&amp;#8217;t have to do this if you already have an nginx setup you like to use. Assuming you followed the above steps the only thing you have left to do is edit the vhost file and add your sites information. I would suggest renaming the vhost file to something a little more descriptive as well. Don&amp;#8217;t forget to create the directory in /var/log/nginx/yoursite or nginx will fail to start. Once you have completed that you just need to symlink your new config into sites-enabled and restart nginx.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% ln -s /etc/nginx/sites-available/vhost /etc/nginx/sites-enabled/vhost
# start nginx
% nginx
# restart nginx
% kill -HUP `cat /var/run/nginx.pid`&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Post Setup Notes&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is one small problem with eventmachine on OpenBSD. When thin intializes eventmachine at application boot time, it tries to use the wrong eventmachine library. You need to use the pure ruby version. An easy way to fix this is to add the following to your .profile&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;export EVENTMACHINE_LIBRARY=&amp;quot;pure_ruby&amp;quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will make eventmachine happy and thin able to run. The reason for choosing thin and nginx over the other implementations is because thin can connect to to nginx via sockets, and nginx is just plain easier to configure, not to mention faster. Obviously you can season this setup to taste if you prefer other stack implementations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Surviving the Reboot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It&amp;#8217;s good practice to have a thin config file that can start your application. Let&amp;#8217;s take a look at how to configure thin for your app.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% mkdir /etc/thin
% thin config -C /etc/thin/your_config.yml -s2 -S /tmp/thin.sock&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will create a thin config file that will spawn to instances of thin (s2) and use sockets instead of ports. You can change the number of instances it spawns or where you want to put your sockets if you so desire. Now that you have a running system, you just need to add one more thing to make sure that your app starts if your server reboots. To make this work you need to do two things.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;% ln -s /usr/local/bin/thin /usr/bin/thin&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will make sure thin is available at boot time. Next you need to add a line in &lt;em&gt;etc/rc.local&lt;/em&gt; to start your app. Add this after the other startup scripts you added previously.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo -n &amp;quot; thin&amp;quot;; thin start -C /etc/thin/your_config.yml&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Happy OpenBSD-ing!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Railsconf Talk</title>
   <link href="http://abedra.github.com/2008/06/01/railsconf-talk.html"/>
   <updated>2008-06-01T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/06/01/railsconf-talk</id>
   <content type="html">&lt;h1 id='railsconf_talk'&gt;Railsconf Talk&lt;/h1&gt;
&lt;p class='meta'&gt;01 Jun 2008&lt;/p&gt;
&lt;p&gt;&lt;a href='http://aaronbedra.com/assets/2008/6/1/de-railing.pdf' title='Here'&gt;Here&lt;/a&gt; are the slides from my railsconf talk. Thank you to all of you that showed up and gave support!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Shame on you O'Reilly!</title>
   <link href="http://abedra.github.com/2008/05/30/shame-on-you-o-reilly.html"/>
   <updated>2008-05-30T00:00:00-07:00</updated>
   <id>http://abedra.github.com/2008/05/30/shame-on-you-o-reilly</id>
   <content type="html">&lt;h1 id='shame_on_you_oreilly'&gt;Shame on you O&amp;#8217;Reilly!&lt;/h1&gt;
&lt;p class='meta'&gt;30 May 2008&lt;/p&gt;
&lt;p&gt;I have a bone to pick with the mensa that decided that it was important to give each Railsconf attendee a badge that had all of their personal information encoded on a barcode on the back side.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;From the back of the badge:&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&amp;#8220;Your name, email address, job title, organization, address and phone number are encoded on this card. Please recycle this card at the end of the conference&amp;#8221;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What? Is there a magical card swiper that gives you money and ever lasting happiness? Exactly why do I need to carry around a badge with all that information? Do they &lt;em&gt;really&lt;/em&gt; expect me to give it back to someone else for &amp;#8220;recycling&amp;#8221; at the end of the conference? This is one badge that is going in the shredder!&lt;/p&gt;</content>
 </entry>
 
 
</feed>