<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Chris Powers : Writings from The Killswitch Collective</title>
    <link>http://www.killswitchcollective.com/blog/index.xml</link>
    <description>These articles were written by Chris Powers for Perspectives, the blog of The Killswitch Collective, a Chicago-based web development, design and communication firm.</description>
    <language>en-us</language>
    <item>
      <title>Super Easy Number Tracking with FatNum.com</title>
      <category>Development</category>
      <description>&lt;h3&gt;What's Your FatNum?&lt;/h3&gt;

&lt;p&gt;Numbers are a big deal. Whether you're talking about business, family, fun, personal goals, a lot can be simply boiled down to one big, fat number...&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;How many people registered for my app?&lt;/li&gt;
  &lt;li&gt;How many batches are left in my database import?&lt;/li&gt;
  &lt;li&gt;How many days left until my birthday?&lt;/li&gt;
  &lt;li&gt;How many pounds have I lost on my diet?&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;And so on...&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So what's the big, fat number that you need to keep track of? Whatever it is, &lt;a href="http://www.fatnum.com" target="_blank"&gt;FatNum.com&lt;/a&gt; can help.&lt;/p&gt;

&lt;h3&gt;What is FatNum.com?&lt;/h3&gt;

&lt;p&gt;FatNum.com lets you signup and start tracking your FatNums right now! Right away you are given a simple Web interface for creating your FatNums and keeping them up to date. Each FatNum is assigned a five-character code, so you can share your FatNum with others discreetly without having to log in.&lt;/p&gt;

&lt;p&gt;For all you programmers who want their Ruby apps to share data with FatNum.com, I've built &lt;a href="http://github.com/chrisjpowers/fat_num/tree/master" target="_blank"&gt;this RubyGem&lt;/a&gt; for easily accessing and updating your FatNums. From the documentation:&lt;/p&gt;

&lt;pre&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;rubygems&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;fat_num&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="ident"&gt;f&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span style="color:#DA4939"&gt;FatNum&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt;your@email.com&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;

&lt;span style="color:#BC9458"&gt;# get your statistic&lt;/span&gt;
&lt;span class="ident"&gt;response&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt;e37gh&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;digit&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 120&lt;/span&gt;
&lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;description&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'batches left'&lt;/span&gt;

&lt;span style="color:#BC9458"&gt;# update your statistic&lt;/span&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;update&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt;e37gh&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="number"&gt;119&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

&lt;span style="color:#BC9458"&gt;# sure enough, our update was successful&lt;/span&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;get&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt;e37gh&lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;digit&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 119&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;There's also some love for all you Mac users out there -- download the &lt;a href="http://www.fatnum.com/FatNum.zip"&gt;FatNum Dashboard Widget&lt;/a&gt; and easily track your FatNums from the comfort of your OSX Dashboard!&lt;/p&gt;

&lt;h3&gt;Any More Examples?&lt;/h3&gt;

&lt;p&gt;Here are a couple FatNums that FatNum.com is using for itself:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://www.fatnum.com/count" target="_blank"&gt;Number of FatNums in the System&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="http://www.fatnum.com/usrct" target="_blank"&gt;Number of Users on FatNum.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;FatNum.com is super simple, almost to a ridiculous degree, but I hope you can find some imaginitive uses for it!&lt;/p&gt;</description>
      <pubDate>Mon, 16 Mar 2009 09:43:28 -0700</pubDate>
      <link>http://www.killswitchcollective.com/articles/57</link>
      <guid>http://www.killswitchcollective.com/articles/57</guid>
    </item>
    <item>
      <title>Introducing FlexibleCSV</title>
      <category>Development</category>
      <description>&lt;blockquote style="padding-left: 0; text-align: center;"&gt;
  &lt;a href="http://github.com/chrisjpowers/flexible_csv/tree/master" target="_blank"&gt;Get FlexibleCSV from GitHub&lt;/a&gt;
&lt;/blockquote&gt;

&lt;h3&gt;A Challenge in Flexibility&lt;/h3&gt;

&lt;p&gt;As part of a contact management system we are building for a client, I encountered a unique challenge with allowing users to upload and import their contacts from CSV files. Usually this would not be a problem, except that in this case there was no standardization to what the header names would be or what order the columns were in. Because the FasterCSV gem relies on using the header names as access keys, this process was suddenly quite complicated.&lt;/p&gt;

&lt;p&gt;One solution would be to create a user interface that would display our database fields, their CSV columns and allow them to pair them up. For example, my database column is 'email' but their CSV column is 'Email Address', so they could mark those as equivalent. What would I do, however, for the users who have a "Full Name" column when I use 'first_name' and 'last_name' database columns? Suddenly the user interface could get very complicated and confusing.&lt;/p&gt;

&lt;h3&gt;Introducing FlexibleCSV&lt;/h3&gt;

&lt;p&gt;Instead, I developed FlexibleCSV, a gem that allows you to parse through a CSV file without knowing exactly what the headers are named. By providing a list of possible header names, you can access all the CSV columns with a uniform interface.&lt;/p&gt;

&lt;pre&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;flexible_csv&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span style="color:#BC9458"&gt;# Arbitrary CSV data&lt;/span&gt;
&lt;span class="ident"&gt;csv_data1&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;%Q{&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Full Name, Email Address&lt;span class="escape"&gt;\n&lt;/span&gt;John Doe, john@doe.com&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;csv_data2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;%Q{&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Email, Name&lt;span class="escape"&gt;\n&lt;/span&gt;john@doe.com, John Doe&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span style="color:#DA4939"&gt;FlexibleCsv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:full_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Full Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Client Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:email&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Email&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Email Address&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;csv_data1&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John Doe'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;email&lt;/span&gt;     &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'john@doe.com'&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;csv_data2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John Doe'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;email&lt;/span&gt;     &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'john@doe.com'&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Both data sets can now be accessed using the uniform &lt;code&gt;#full_name&lt;/code&gt; and &lt;code&gt;#email&lt;/code&gt; accessors.&lt;/p&gt;

&lt;h3&gt;Handling Complexity with Adapters&lt;/h3&gt;

&lt;p&gt;Going back to my original example, how would we handle CSV files that separated first and last names when my database uses the full name? Or vis versa? Though I considered adding this kind of functionality to the FlexibleCSV gem, ultimately I thought it best to keep that kind of logic in a separate adapter class. For example:&lt;/p&gt;

&lt;pre&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span style="color:#A5C261"&gt;flexible_csv&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span style="color:#BC9458"&gt;# Arbitrary CSV data&lt;/span&gt;
&lt;span class="ident"&gt;csv_data1&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;%Q{&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Full Name&lt;span class="escape"&gt;\n&lt;/span&gt;John Doe&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;
&lt;span class="ident"&gt;csv_data2&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;%Q{&lt;/span&gt;&lt;span style="color:#A5C261"&gt;First Name, Last Name&lt;span class="escape"&gt;\n&lt;/span&gt;John,Doe&lt;/span&gt;&lt;span class="punct"&gt;}&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span style="color:#DA4939"&gt;FlexibleCsv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:full_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Full Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Client Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:first_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;First Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;First&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span class="ident"&gt;csv&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;column&lt;/span&gt; &lt;span style="color:#6E9CBE"&gt;:last_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Last Name&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Last&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;Surname&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

&lt;span style="color:#CC7833"&gt;class &lt;/span&gt;&lt;span class="class"&gt;CsvAdapter&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span style="color:#D0D0FF"&gt;@row&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

  &lt;span style="color:#CC7833"&gt;def &lt;/span&gt;&lt;span class="method"&gt;full_name&lt;/span&gt;
    &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span style="color:#A5C261"&gt;&lt;span class="expr"&gt;#{row.first_name}&lt;/span&gt; &lt;span class="expr"&gt;#{row.last_name}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

  &lt;span style="color:#CC7833"&gt;def &lt;/span&gt;&lt;span class="method"&gt;last_name&lt;/span&gt;
    &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_name&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt; &lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;last&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

  &lt;span style="color:#CC7833"&gt;def &lt;/span&gt;&lt;span class="method"&gt;first_name&lt;/span&gt;
    &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first_name&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;split&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span style="color:#A5C261"&gt; &lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

  &lt;span style="color:#CC7833"&gt;def &lt;/span&gt;&lt;span class="method"&gt;method_missing&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;method_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;method_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span style="color:#CC7833"&gt;end&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;csv_data1&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;ad_row&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span style="color:#DA4939"&gt;CsvAdapter&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt;  &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John Doe'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first_name&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_name&lt;/span&gt;  &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'Doe'&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;parser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;parse&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;csv_data2&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;each&lt;/span&gt; &lt;span style="color:#CC7833"&gt;do&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt;
  &lt;span class="ident"&gt;ad_row&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span style="color:#DA4939"&gt;CsvAdapter&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;row&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;full_name&lt;/span&gt;  &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John Doe'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first_name&lt;/span&gt; &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'John'&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="ident"&gt;ad_row&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;last_name&lt;/span&gt;  &lt;span style="color:#BC9458"&gt;#=&amp;gt; 'Doe'&lt;/span&gt;
&lt;span style="color:#CC7833"&gt;end&lt;/span&gt;
&lt;/pre&gt;

&lt;p&gt;Using the adapter class, we can once again access each row of data from any CSV file with a uniform interface.&lt;/p&gt;

&lt;h3&gt;Go Get It!&lt;/h3&gt;

&lt;p&gt;To use the FlexibleCSV gem, you can follow or fork the project &lt;a href="http://github.com/chrisjpowers/flexible_csv/tree/master" target="_blank"&gt;on GitHub&lt;/a&gt; or just install the gem:&lt;/p&gt;

&lt;pre&gt;
sudo gem install chrisjpowers-flexible_csv
&lt;/pre&gt;</description>
      <pubDate>Thu, 19 Feb 2009 12:46:53 -0800</pubDate>
      <link>http://www.killswitchcollective.com/articles/54</link>
      <guid>http://www.killswitchcollective.com/articles/54</guid>
    </item>
    <item>
      <title>Happy Birthday, Perspectives!</title>
      <category>Perspectives</category>
      <description>&lt;h3&gt;One Year Down...&lt;/h3&gt;

&lt;p&gt;Today, Killswitch is celebrating the 1-year birthday of our blog &lt;em&gt;Perspectives&lt;/em&gt;! Since &lt;a href="http://killswitchcollective.com/articles/6" target="_blank"&gt;its introduction&lt;/a&gt;, &lt;em&gt;Perspectives&lt;/em&gt; has been our outlet for giving back to the communities we rely on. It has been a lot of fun sharing our thoughts and ideas with you, so be assured that we will continue delivering hot, fresh content on a weekly basis.&lt;/p&gt;

&lt;p&gt;Over the last twelve months I have been asked a few times:&lt;/p&gt; 

&lt;blockquote&gt;Why go to so much trouble to blog? Aren't you just giving away your trade secrets?&lt;/blockquote&gt; 

&lt;p&gt;It's true that &lt;em&gt;Perspectives&lt;/em&gt; is no money maker &amp;mdash; obviously no one is paying to read these articles, and we certainly wouldn't want them to! So why do we continue to ask our entire staff at Killswitch to spend valuable man-hours writing?&lt;/p&gt;

&lt;h3&gt;And Many More&lt;/h3&gt;

&lt;p&gt;As I mentioned before, a big part of it is the importance of giving back to the communities that support our business. From a development standpoint, we solely use &lt;a href="http://en.wikipedia.org/wiki/Open_source" target="_blank"&gt;Open Source&lt;/a&gt; coding languages, libraries and programs, which means that these tools have been provided free of charge. In stark contrast to Microsoft tools like .NET which are supported internally and leased to developers, Open Source code is maintained by a community of volunteers who are concerned enough about the success of the industry to pitch in and help.&lt;/p&gt;

&lt;p&gt;Every time I run into a bug while developing a Web app, my first inclination is to Google my issue and see if someone has already written a blog article with a fitting solution &amp;mdash; and often times that works! Maintaining &lt;em&gt;Perspectives&lt;/em&gt; with helpful tutorials and free downloadable code is our way of saying 'thank you' to the community and giving something back.&lt;/p&gt;

&lt;h3&gt;Keep It Coming&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Perspectives&lt;/em&gt; is a place where we can show you a more candid, honest look at the people who make The Killswitch Collective what it is. This is our opportunity to express our passion for &lt;a href="http://www.killswitchcollective.com/blog/categories/Design" target="_blank"&gt;intuitive design&lt;/a&gt;, &lt;a href="http://www.killswitchcollective.com/blog/categories/Development" target="_blank"&gt;clever development&lt;/a&gt; and &lt;a href="http://www.killswitchcollective.com/blog/categories/Perspectives" target="_blank"&gt;fruitful business relationships&lt;/a&gt;. We want to show our readers how we think, how we work through problems and how we strive to make the Web a better place.&lt;/p&gt;

&lt;p&gt;With one year under our belts, we're just starting to get warmed up. Keep checking back each week for more articles about development, design and anything else we're thinking about. If you are new to &lt;em&gt;Perspectives&lt;/em&gt;, here are a few tips to help get you started:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="http://feeds.feedburner.com/killswitchcollective/perspectives" target="_blank"&gt;Subscribe&lt;/a&gt; to &lt;em&gt;Perspectives&lt;/em&gt; by adding this URL to your RSS reader: http://feeds.feedburner.com/killswitchcollective/perspectives. Not using an RSS reader yet? &lt;a href="http://reader.google.com" target="_blank"&gt;Try Google Reader!&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Start following &lt;code&gt;@KSCollective&lt;/code&gt; on Twitter for up-to-the-minute updates about what we are working on and thinking about.&lt;/li&gt;
  &lt;li&gt;Use the Category links in the sidebar to narrow down articles to topics that interest you (&lt;a href="http://killswitchcollective.com/blog/categories/Design" target="_blank"&gt;design&lt;/a&gt;,  &lt;a href="http://killswitchcollective.com/blog/categories/Development" target="_blank"&gt;development&lt;/a&gt;, etc).&lt;/li&gt;
  &lt;li&gt;Click on an author's picture at the bottom of their articles to read their other entries.&lt;/li&gt;
  &lt;li&gt;&lt;a href="mailto:info@killswitchcollective.com"&gt;Drop us a note&lt;/a&gt;, we'd love to answer any questions!&lt;/li&gt;
&lt;/ul&gt;</description>
      <pubDate>Fri, 30 Jan 2009 07:27:43 -0800</pubDate>
      <link>http://www.killswitchcollective.com/articles/52</link>
      <guid>http://www.killswitchcollective.com/articles/52</guid>
    </item>
  </channel>
</rss>
