<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>My name is Matt Gaidica, this is where I write about technical things.</description><title>Bytes of Pi</title><generator>Tumblr (3.0; @bytesofpi)</generator><link>http://bytesofpi.com/</link><item><title>Brandr Open Sourced</title><description>&lt;a href="https://github.com/mattgaidica/brandr"&gt;Brandr Open Sourced&lt;/a&gt;: &lt;p&gt;&lt;img alt="" src="http://file.gaidi.ca/image/3b462z2c3N2K/Screen%20Shot%202013-02-25%20at%2010.06.07%20PM.png"/&gt;&lt;/p&gt;
&lt;p&gt;I have no reason to call this “intellectual property” anymore. I have released the code that drives this cool little demo: &lt;a href="http://landr.co/brandr/" target="_blank"&gt;&lt;a href="http://landr.co/brandr/" target="_blank"&gt;http://landr.co/brandr/&lt;/a&gt;&lt;/a&gt; This project was about 2 weeks of coding, testing, and understanding—having late nights, and a lot of white-boarding to figure out the best way to extract colors from brands. Notice, I say “brands”. It’s not just colors from an image, it’s the human interpretation of a gestalt; and that’s why it is a tough problem. Click on the title above, or &lt;a href="https://github.com/mattgaidica/brandr" target="_blank"&gt;here&lt;/a&gt; for the Github repo.&lt;/p&gt;</description><link>http://bytesofpi.com/post/44034551801</link><guid>http://bytesofpi.com/post/44034551801</guid><pubDate>Mon, 25 Feb 2013 22:05:00 -0500</pubDate><category>brandr</category><category>branding</category><category>colors</category><category>ai</category><category>landr</category></item><item><title>Installing suPHP with Plesk 11 on Media Temple DV4</title><description>&lt;p&gt;I ran into major dependency issues trying to follow &lt;a href="http://wiki.mediatemple.net/w/(dv)_4.0_-_Making_It_Better_::_Using_mod_suphp_with_Plesk" target="_blank"&gt;this tutorial&lt;/a&gt; provided in the Media Temple knowledge-base. Normally it is recommended to install &lt;a href="http://www.suphp.org/DocumentationView.html?file=apache/CONFIG" target="_blank"&gt;suPHP&lt;/a&gt; by compiling it from source (as mentioned in the tutorial), but mainly because of the mode that suPHP is put into during the installation. The reckoning for suPHP is well-put &lt;a href="http://kb.acenet.us/LAMP_Server_Installation_Guide_on_Debian_6_(Squeeze)" target="_blank"&gt;here&lt;/a&gt;, with the three modes of operation being:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;owner: Run scripts with owner UID/GID&lt;/li&gt;
&lt;li&gt;force: Run scripts with UID/GID specified in Apache configuration&lt;/li&gt;
&lt;li&gt;paranoid: Run scripts with owner UID/GID but also check if they match the UID/GID specified in the Apache configuration&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The advantage of compiling from source is that suPHP can run in paranoid mode—however, as the previous link states: &lt;em&gt;Although suPHP states that the default mode is &amp;#8220;paranoid&amp;#8221;, the libapache2-mod-suphp is installed in &amp;#8220;owner&amp;#8221; mode by default. When suPHP is installed in &amp;#8220;owner&amp;#8221; mode, the directive suPHP_UserGroup is not recognized which is required for &amp;#8220;force&amp;#8221; or &amp;#8220;paranoid&amp;#8221; mode.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Running suPHP in owner mode doesn&amp;#8217;t seem all-that-bad, considering it &lt;em&gt;is&lt;/em&gt; in fact the default for some installations. However, the comment about not having access to the &amp;#8220;suPHP_UserGroup&amp;#8221; within your configuration file is true, and if you try to restart Apache with it in there (as the Media Temple tutorial suggests), it will result in an error, and possibly crash your server.&lt;/p&gt;
&lt;p&gt;My workaround is to remove any of the lines that include &amp;#8220;suPHP_UserGroup&amp;#8221;, and simply use yum to install suPHP, which lets you skip steps 1-4 in the tutorial.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;yum install mod_suphp&lt;/pre&gt;</description><link>http://bytesofpi.com/post/43967654859</link><guid>http://bytesofpi.com/post/43967654859</guid><pubDate>Mon, 25 Feb 2013 01:13:00 -0500</pubDate><category>yum</category><category>plesk</category><category>suphp</category><category>mediatemple</category><category>dv4</category></item><item><title>SlipPay: An Online Receipt Marketplace</title><description>&lt;a href="http://slippay.herokuapp.com/"&gt;SlipPay: An Online Receipt Marketplace&lt;/a&gt;: &lt;p&gt;I couldn’t understand why cash-based receipts have not been exploited. It is so seemingly simple to return your “used” stuff, if only you had that magic receipt. Let me know what you think!&lt;/p&gt;</description><link>http://bytesofpi.com/post/43250625157</link><guid>http://bytesofpi.com/post/43250625157</guid><pubDate>Sat, 16 Feb 2013 15:33:00 -0500</pubDate><category>slippay</category><category>receipts</category><category>market</category><category>craigslist</category><category>ebay</category></item><item><title>Why I can Judge Your Design Work</title><description>&lt;p&gt;&lt;strong&gt;I write code. I love logic.&lt;/strong&gt; And I still know what &lt;em&gt;beautiful&lt;/em&gt; is.&lt;/p&gt;
&lt;p&gt;Of course, there is no true judge of artful things. However, artists still have a tendency to believe their eyes are not only different, but a better judge of artistic character, aesthetic presence, and visual impact. This is wrong, and I&amp;#8217;ll tell you why.&lt;/p&gt;
&lt;p&gt;I may not be a wonderful chef, but I know when my steak is under-cooked, or over-seasoned. I am not on any New York Times best-seller list, but I can tell who is a good novelist after a couple chapters. I can&amp;#8217;t paint, but it is easy to see when someone has a grasp on lighting, shapes, and colors. I don&amp;#8217;t have many music abilities, but I could spot the difference between a high school band, and a renowned symphony orchestra.&lt;/p&gt;
&lt;p&gt;Being a good creator has no affect on your ability to consume, and no affect on your ability to judge– it may only affect your historical knowledge or appreciation of the subject matter. When you compose a piece of art, whether it be digital or mechanical, on canvas or on film, you must accept the interpretation of the consumer.&lt;/p&gt;
&lt;p&gt;If you can bring new perspective to your artwork by telling a story, or bringing forth some element of enlightenment in those who consume it, you are truly a great artist. But if you think that because someone doesn&amp;#8217;t see it your way, or find something more or less beautiful than you, do not blame it on their experience, their lifestyle, their career, or your ignorant predispositions about their ability to artistically, aesthetically, or visually intake something– &lt;strong&gt;blame it on your shitty art&lt;/strong&gt;.&lt;/p&gt;</description><link>http://bytesofpi.com/post/42026581935</link><guid>http://bytesofpi.com/post/42026581935</guid><pubDate>Fri, 01 Feb 2013 11:09:00 -0500</pubDate><category>art</category></item><item><title>Creating Rows with ExpressionEngine and a Grid</title><description>&lt;p&gt;Below is an image from my digital library that I developed to help me organize my research for an &lt;a href="http://gaidi.ca" title="Left: Your Brain &amp;amp; Your Work" target="_blank"&gt;upcoming book&lt;/a&gt;. It uses a responsive grid, and I&amp;#8217;ll show you how to create it using &lt;a href="http://twitter.github.com/bootstrap/" target="_blank"&gt;Bootstrap&lt;/a&gt; and methods available within &lt;a href="http://ellislab.com/expressionengine" target="_blank"&gt;ExpressionEngine&lt;/a&gt; (no &lt;a href="http://en.wikipedia.org/wiki/Modulo_operation" target="_blank"&gt;modulo&lt;/a&gt;!).&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="http://media.tumblr.com/cfa6553fc963b00837110c62aa974594/tumblr_inline_mhjsmwAnep1qz4rgp.png"/&gt;&lt;/p&gt;
&lt;p&gt;Let&amp;#8217;s take a look at how Bootstrap implements their grid (knowing other grid systems are similar), and in particular, a 4-column grid.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;div class="row"&amp;gt;
  &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
  &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The only complexity within ExpressionEngine you face is that you have repeating elements for the &amp;#8220;span3&amp;#8221; class, but the rows also need to repeat as the page continues! The &lt;a href="http://ellislab.com/expressionengine/user-guide/modules/channel/channel_entries.html#switch" target="_blank"&gt;switch statement&lt;/a&gt; comes to the rescue in a somewhat unexpected way.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;lt;div class="row"&amp;gt;
  {exp:channel:entries channel="books" orderby="title" sort="asc" dynamic="no"}
    &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
    &amp;lt;div class="span3"&amp;gt;&amp;lt;/div&amp;gt;
    {switch='|||&amp;lt;/div&amp;gt;&amp;lt;div class="row"&amp;gt;'}
  {/exp:channel:entries}
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Why is this a little tricky? Well, even though the entire EE channel loop appears to be wrapped by a row element, it&amp;#8217;s not. The closing (and opening) of the first, and all subsequent rows, is handled in the switch statement. The last and final closing &amp;#8220;&amp;lt;/div&amp;gt;&amp;#8221; is actually closing a row that came from the switch statement.&lt;/p&gt;
&lt;p&gt;If you are used to hardcoding this type of stuff in PHP, your mind may instantly jump to using some type of modulo plugin to do this, but fortunately you can scratch that complexity right out. Here is what my entire page looks like, using &lt;a href="http://pixelandtonic.com/assets" target="_blank"&gt;Assets&lt;/a&gt; for the image.&lt;/p&gt;
&lt;pre&gt;{embed="partials/_head"}

&amp;lt;h2&amp;gt;Books&amp;lt;/h2&amp;gt;

&amp;lt;div class="row"&amp;gt;
  {exp:channel:entries &lt;span&gt;channel="books" orderby="title" sort="asc" dynamic="no"&lt;/span&gt;&lt;span&gt; disable="custom_ﬁelds|member_data|pagination|trackbacks"}&lt;/span&gt;&lt;br/&gt;    {if no_results}
      &amp;lt;div class="span12"&amp;gt;&amp;lt;p&amp;gt;No entries yet.&amp;lt;/p&amp;gt;&amp;lt;/div&amp;gt;
    {/if}
    &amp;lt;div class="span3"&amp;gt;
      {research_cover}
        &amp;lt;a href="{path='book/entry/{url_title}'}"&amp;gt;&amp;lt;img class="img-polaroid img-rounded" src="{url:tall}" alt="{alt_text}"/&amp;gt;&amp;lt;/a&amp;gt;
      {/research_cover}
      &amp;lt;h5&amp;gt;&amp;lt;a href="{path='book/entry/{url_title}'}"&amp;gt;{title}&amp;lt;/a&amp;gt;&amp;lt;/h5&amp;gt;
      &amp;lt;p class="center"&amp;gt;&amp;lt;small&amp;gt;{if book_bought}&amp;amp;#x2713; you own this{/if}&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
    {switch='|||&amp;lt;/div&amp;gt;&amp;lt;div class="row"&amp;gt;'}
  {/exp:channel:entries}
&amp;lt;/div&amp;gt;

{embed="partials/_foot"}
&lt;/pre&gt;</description><link>http://bytesofpi.com/post/42026473860</link><guid>http://bytesofpi.com/post/42026473860</guid><pubDate>Fri, 01 Feb 2013 11:07:00 -0500</pubDate><category>expressionengine</category><category>modulo</category><category>grid</category><category>bootstrap</category><category>switch</category><category>book writing</category></item><item><title>Timebomb.it is a Time-sensitive Short Link for Passwords</title><description>&lt;p&gt;I built &lt;a href="https://timebomb.it/" title="Time-sensitive Short Link for Passwords" target="_blank"&gt;timebomb.it&lt;/a&gt; a long time ago and gave it a quick refresh this afternoon. I still see this problem popup all over the place– people sending passwords in emails. Worse yet, starting the email with, &amp;#8220;here is the password&amp;#8221;. All it takes is access to someones email account to retrieve all these passwords, or bank account numbers, or social security numbers.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="http://media.tumblr.com/627fea7cc98b8c31cb52f3f4df70d164/tumblr_inline_mhes7itHXM1qz4rgp.png"/&gt;&lt;/p&gt;

&lt;p&gt;This mobile-friendly website allows you to make confidential information available for only 1 hour, 1 day, or 1 week. When the time is up, so is the data, and it is erased forever. Everything runs under an SSL certificate (HTTPS) so everything transmitted is encrypted, and secure. Also, every link comes in a clean, sendable format (eg. &amp;#8220;https://timebomb.it/637jv8gfmd&amp;#8221;). Give it a try, and save yourself (and your clients!) from a security catastrophe down the road.&lt;/p&gt;</description><link>http://bytesofpi.com/post/41814919357</link><guid>http://bytesofpi.com/post/41814919357</guid><pubDate>Tue, 29 Jan 2013 17:43:00 -0500</pubDate><category>security</category><category>time</category><category>limited</category><category>shortlink</category><category>passwords</category><category>logins</category></item><item><title>I added an ultra low-profile sliding table top (on an angle!) to...</title><description>&lt;img src="http://25.media.tumblr.com/01fc470096353690f1c50c230096fff5/tumblr_mhd2aoXrK51r8s4oao2_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://25.media.tumblr.com/9188ffad5f3919cd390ff57fb4ee5438/tumblr_mhd2aoXrK51r8s4oao1_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://24.media.tumblr.com/c184c5ebe43c74469b2f5851f48928f9/tumblr_mhd2aoXrK51r8s4oao3_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;p&gt;I added an ultra low-profile sliding table top (on an angle!) to my desk this weekend. It collapses just enough so my cup of water always has a spot on a nice felt pad. It has an 18” throw which is perfect for a laptop, some books, or bundles of papers. It slides, it floats, it’s simple, and only cost $28 worth of parts at Home Depot. Even with that fancy chair from Target I am still sub-$200 on this desk (&lt;a href="http://tmblr.co/ZPk4NwQpzVyZ" title="A Coder's Workspace" target="_blank"&gt;see my first post about this&lt;/a&gt;).&lt;/p&gt;</description><link>http://bytesofpi.com/post/41740946833</link><guid>http://bytesofpi.com/post/41740946833</guid><pubDate>Mon, 28 Jan 2013 19:20:00 -0500</pubDate><category>desk</category><category>retracetable</category><category>sliding</category><category>workspace</category><category>hidden</category><category>floating</category></item><item><title>Git Video - Supplementing Github Commits with Video!</title><description>&lt;div class="notify"&gt;Special thanks to the team over at &lt;a href="http://nimbb.com" target="_blank"&gt;Nimbb&lt;/a&gt; for sponsoring this project with some free video space. A company willing to go out of the way for independent developers deserves a look— so &lt;a href="http://nimbb.com" target="_blank"&gt;check them out&lt;/a&gt;!&lt;/div&gt;
&lt;p&gt;Ever come back to a project and completely forget how all the pieces fit together? Supplement your commits with &lt;a href="http://gitvideo.herokuapp.com/" title="Git Video" target="_blank"&gt;Git Video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" src="http://f.cl.ly/items/2a200N352f422f0x332f/Screen%20shot%202013-01-23%20at%204.40.27%20PM.png"/&gt;&lt;/p&gt;
&lt;p&gt;That half-sentence you throw into the commit message usually does no help when you have walked away from a project for more than a day. Projects take major evolutions— architecture, ideologies, and approaches to problems are constantly changing, and documenting them becomes hard. A short video connected to each commit on Github is perfect, and lets you use gestures, inflection, and visuals to help you remember what state the project is in at that point in time.&lt;/p&gt;
&lt;p&gt;&lt;img alt="image" height="327" src="http://f.cl.ly/items/0E1I3j102Z15232d2q0O/Screen%20shot%202013-01-23%20at%204.38.21%20PM.png" width="719"/&gt;&lt;/p&gt;
&lt;p&gt;Doing this once a day will help you battle that incessant, twenty-minute, &amp;#8220;back into the groove&amp;#8221; you usually have to entertain when switching between projects. It was created in a night on &lt;a href="http://rubyonrails.org/" title="Ruby on Rails" target="_blank"&gt;Rails&lt;/a&gt;, uses &lt;a href="http://developer.github.com/v3/" target="_blank"&gt;Github&amp;#8217;s API&lt;/a&gt;, designed with &lt;a href="http://twitter.github.com/bootstrap/" target="_blank"&gt;Bootstrap&lt;/a&gt;, launched on &lt;a href="http://heroku.com" target="_blank"&gt;Heroku&lt;/a&gt;, monitored with &lt;a href="http://newrelic.com/" title="New Relic" target="_blank"&gt;New Relic&lt;/a&gt;, and relies on &lt;a href="http://nimbb.com/" target="_blank"&gt;Nimbb&lt;/a&gt; for the video embedding.&lt;/p&gt;</description><link>http://bytesofpi.com/post/41303758361</link><guid>http://bytesofpi.com/post/41303758361</guid><pubDate>Wed, 23 Jan 2013 16:45:00 -0500</pubDate><category>github</category><category>video</category><category>commit</category><category>heroku</category><category>bootstrap</category><category>nimbb</category><category>rails</category><category>newrelic</category></item><item><title>"Before the “lean startup methodology” made beta testing de rigeur, companies would..."</title><description>“&lt;p&gt;Before the “lean startup methodology” made beta testing de rigeur, companies would perform “pilots” with little to no feedback from the front lines. This strategy of ignorance often led to the development of technology that actually made educators less efficient.&lt;/p&gt;

&lt;p&gt;As a teacher and one allowed into the inner sanctum of ImagineK12, I can tell you that today’s entrepreneurs are different. They care about listening to teachers and acting on insightful, productive feedback. They know that it’s not enough to be a respectful and good listener; these entrepreneurs have learned to let teachers know when they act on the feedback they’ve received.&lt;/p&gt;”&lt;br/&gt;&lt;br/&gt; - &lt;em&gt;Jennie Dougherty, a teacher in Brockton, Mass., who cofounded &lt;a href="http://edsurge.us2.list-manage2.com/track/click?u=439db75adf017b97887993422&amp;id=52ee6e18d7&amp;e=e241d27450" target="_blank"&gt;Edupgrade&lt;/a&gt; and blogs at &lt;a href="http://edsurge.us2.list-manage.com/track/click?u=439db75adf017b97887993422&amp;id=41bf6da2d3&amp;e=e241d27450" target="_blank"&gt;BetaClassroom&lt;/a&gt;.&lt;/em&gt;</description><link>http://bytesofpi.com/post/29561009124</link><guid>http://bytesofpi.com/post/29561009124</guid><pubDate>Thu, 16 Aug 2012 13:50:00 -0400</pubDate></item><item><title>Simple Status Ticker for API Endpoints</title><description>&lt;p&gt;When you are deploying code left-and-right, even in a test-driven development cycle, sometimes you still want the piece of mind that your website is responding. In my case, this is specific to API endpoints and different API environments we run our products on.&lt;/p&gt;
&lt;p&gt;&lt;img align="middle" alt="Status Ticker" height="374" src="http://media.tumblr.com/tumblr_m8icvtSOCK1r4ovy3.png" width="502"/&gt;&lt;/p&gt;
&lt;p&gt;This script allows you to leave a mini terminal window on your screen that will refresh the status of a website at an interval of your choice. I use two gems, the first is to make the text colors pretty, and the second is for making the HTTP calls- install them like so:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;gt; gem install httparty
&amp;gt; gem install terminal-display-colors
&lt;/pre&gt;
&lt;p&gt;Below is the code, which can also be found on &lt;a href="https://gist.github.com/3308319" title="Status Ticker" target="_blank"&gt;this Github gist&lt;/a&gt;.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;require 'HTTParty'
require 'terminal-display-colors'
require 'json'

# set your endpoints!
endpoints = {
  "Google" =&amp;gt; "http://google.com",
  "Twitter" =&amp;gt; "http://twitter.com"
}
# seconds to sleep between pings
sleep_seconds = 10

buffer = []

def diff start, finish
  ((finish-start) * 1000.0).round(2)
end

def print_flush str
  print str
  $stdout.flush
end

while(true)
  # clear terminal
  buffer &amp;lt;&amp;lt; "\e[H\e[2J"
  response_times = []
  # loop endpoints
  endpoints.each do |name, url|
    begin
      t1 = Time.now
      response = HTTParty.get url
      t2 = Time.now
      if response.code == 200
        response_times &amp;lt;&amp;lt; diff(t1,t2)
        buffer &amp;lt;&amp;lt; "#{name.upcase} : " + response.message.green + " (#{response_times.last}ms)".yellow
      else
        buffer &amp;lt;&amp;lt; "#{name.upcase} : " + response.message.red
      end
    rescue =&amp;gt; e
      buffer &amp;lt;&amp;lt; "#{name.upcase} : " + 'Connection Error'.red 
    end
  end

  buffer &amp;lt;&amp;lt; "\n"
  # display avg and max response times
  unless response_times.empty?
    buffer &amp;lt;&amp;lt; "avg : #{(response_times.inject{ |sum, el| sum + el }.to_f / response_times.size).round(2)}ms".cyan
    buffer &amp;lt;&amp;lt; "max : #{response_times.max}ms".cyan
  else
    buffer &amp;lt;&amp;lt; 'No response times.'.cyan
  end
  # send buffered text to terminal
  puts buffer.join("\n")
  buffer.clear

  # sleep
  sleep_seconds.times
    sleep 1
    print_flush '.'
  end
end&lt;/pre&gt;
&lt;p&gt;To use the ticker, take the code and put it into a file named `status.rb` and run the following in terminal from the directory the file is located:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;&amp;gt; ruby status.rb
&lt;/pre&gt;
&lt;p&gt;To exit the ticker, use control+c on your keyboard.&lt;/p&gt;</description><link>http://bytesofpi.com/post/29078454728</link><guid>http://bytesofpi.com/post/29078454728</guid><pubDate>Thu, 09 Aug 2012 18:02:25 -0400</pubDate><category>ruby</category><category>ticker</category><category>status</category><category>api</category><category>endpoints</category><category>terminal</category></item><item><title>Forcing SSL in a Sinatra App</title><description>&lt;p&gt;When deploying on Heroku, you can &lt;a href="https://devcenter.heroku.com/articles/ssl#piggyback-ssl-myappherokucom-and-myappherokuappcom-only" title="Heroku SSL piggy back" target="_blank"&gt;piggy back on their SSL certificate&lt;/a&gt;, which allows you to have a secure connection right away without any SSL configurations of your own. I think this is a great solution for a lot of people until you need a really pretty URL. Because this is possible, you should use it, and if your building an API you should also think about forcing different environments to require SSL. Here is a simple implementation in my `app.rb` file:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;class Myapi &amp;lt; Sinatra::Application
  ActiveRecord::Base.default_timezone = :utc

  configure :development, :test do
    set :host, 'localhost:9999'
    set :force_ssl, false
  end
  configure :staging do
    set :host, 'my-api-staging.herokuapp.com'
    set :force_ssl, true
  end
  configure :production do
    set :host, 'my-api.herokuapp.com'
    set :force_ssl, true
  end

  before do
    content_type :json
    ssl_whitelist = ['/calendar.ics']
    if settings.force_ssl &amp;amp;&amp;amp; !request.secure? &amp;amp;&amp;amp; !ssl_whitelist.include?(request.path_info)
      halt json_status 400, "Please use SSL at https://#{settings.host}"
    end
  end
end

require_relative 'application/helpers/init'
require_relative 'application/routes/init'
require_relative 'application/models/init'
require_relative 'application/core_extensions/init'
&lt;/pre&gt;
&lt;p&gt;I have left some of my app-specific code in there as well, but I am sure you can dig around that to see how SSL is forced. Notice that because downloading `.ics` files shouldn&amp;#8217;t require SSL, or in other words, it shouldn&amp;#8217;t fail if the user uses `http`, it is included in a whitelist array.&lt;/p&gt;</description><link>http://bytesofpi.com/post/28952453059</link><guid>http://bytesofpi.com/post/28952453059</guid><pubDate>Tue, 07 Aug 2012 22:23:48 -0400</pubDate><category>ssl</category><category>sinatra</category><category>ruby</category><category>heroku</category><category>https</category></item><item><title>Multi-environment post_build_hook using tddium, Heroku, and Ruby Sinatra</title><description>&lt;p&gt;We have been using &lt;a href="https://www.tddium.com/" title="tddium" target="_blank"&gt;tddium&lt;/a&gt; as a deployment tool for our Ruby Sinatra API for some time now. It has been working great and now manages deployment for 7 of our API environments. We have ran into a few small issues, but there are some sharp engineers on support, so issues get fixed fast. The most recent develop in our system is to implement a post build hook to run migrations after the app is deployed on Heroku.&lt;/p&gt;
&lt;p&gt;One of the straight-forward adjustments I had to make to their &lt;a href="https://gist.github.com/2639790" title="tddium gist" target="_blank"&gt;gist&lt;/a&gt; is to dynamically set the app name based on the branch that was pushed to Github. In our case, each Heroku app (&amp;#8220;environment&amp;#8221;) has a git branch, and this is also how tddium sets up test suites, so everything jives.&lt;/p&gt;
&lt;p&gt;The portion that required some support was apparently due to some dependency issues with my gems and the way the git repo was being pushed from tddium. The first step was to add the heroku gem to my gemfile, and from there, it was to modify the tddium post_build_hook a little bit. Here is the full version:&lt;/p&gt;
&lt;pre class="prettyprint"&gt;namespace :tddium do
  desc "post_build_hook"
  task :post_build_hook do
    return unless ENV["TDDIUM_MODE"] == "ci"
    return unless ENV["TDDIUM_BUILD_STATUS"] == "passed"

    dir = File.expand_path("~/.heroku/")
    heroku_email = ENV["HEROKU_EMAIL"]
    heroku_api_key = ENV["HEROKU_API_KEY"]
    current_branch = `git symbolic-ref HEAD 2&amp;gt;/dev/null | cut -d"/" -f 3-`.strip
    abort "invalid current branch" unless current_branch
    puts "Current Branch: #{current_branch}"

    case current_branch
      when 'integration'
        app_name = 'matts-api-integration'
      when 'staging'
        app_name = 'matts-api-staging'
      when 'production'
        app_name = 'matts-api'
      when 'demo'
        app_name = 'matts-api-demo'
      when 'demo-staging'
        app_name = 'matts-api-demo-staging'
      when 'pilot'
        app_name = 'matts-api-pilot'
      when 'pilot-staging'
        app_name = 'matts-api-pilot-staging'
    end

    return unless defined? app_name

    puts "App Name: #{app_name}"
    push_sha = `git rev-parse HEAD`
    push_target = "git@heroku.com:#{app_name}.git"

    abort "invalid current branch" unless current_branch

    FileUtils.mkdir_p(dir) or abort "Could not create #{dir}"

    puts "Writing Heroku Credentials"
    File.open(File.join(dir, "credentials"), "w") do |f|
      f.write([heroku_email, heroku_api_key].join("\n"))
      f.write("\n")
    end

    File.open(File.expand_path("~/.netrc"), "a+") do |f|
      ['api', 'code'].each do |host|
        f.puts "machine #{host}.heroku.com"
        f.puts "  login #{heroku_email}"
        f.puts "  password #{heroku_api_key}"
      end
    end
    
    puts "Pushing to Heroku: #{push_target}..."
    cmd "git push #{push_target} HEAD:master --force" or abort "could not push to #{push_target}"

    puts "Running Heroku Migrations..."
    cmd "heroku run rake db:migrate --app #{app_name}" or abort "aborted migrations"

    puts "Restarting Heroku..."
    cmd "bundle exec heroku restart --app #{app_name}" or abort "aborted heroku restart" 

    puts "Post Build Complete!"
  end
end
&lt;/pre&gt;</description><link>http://bytesofpi.com/post/28951195588</link><guid>http://bytesofpi.com/post/28951195588</guid><pubDate>Tue, 07 Aug 2012 22:05:25 -0400</pubDate><category>ruby</category><category>sinatra</category><category>api</category><category>tddium</category><category>heroku</category><category>post_build_hook</category><category>environment</category></item><item><title>A new workspace from a $150 Ikea trip. The lights can be set to...</title><description>&lt;img src="http://25.media.tumblr.com/tumblr_m8axgrCTau1r8s4oao1_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://24.media.tumblr.com/tumblr_m8axgrCTau1r8s4oao5_r1_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://25.media.tumblr.com/tumblr_m8axgrCTau1r8s4oao2_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;img src="http://24.media.tumblr.com/tumblr_m8axgrCTau1r8s4oao6_r1_500.jpg"/&gt;&lt;br/&gt; &lt;br/&gt;&lt;p&gt;A new workspace from a $150 Ikea trip. The lights can be set to different colors, which can signal to others that you are busy or free to chat (“wired in”, you might say). The lights can also gently fade through the color spectrum, which is relaxing. &lt;a href="https://www.facebook.com/media/set/?set=a.594899984039.2053824.53801930&amp;type=1&amp;l=525a892f14" title="Workspaces" target="_blank"&gt;View the Facebook album of my workspaces&lt;/a&gt;.&lt;/p&gt;</description><link>http://bytesofpi.com/post/28789047075</link><guid>http://bytesofpi.com/post/28789047075</guid><pubDate>Sun, 05 Aug 2012 17:38:00 -0400</pubDate><category>workspace</category><category>standing desk</category><category>developer</category><category>ikea</category><category>coding</category><category>lights</category></item><item><title>Lazy Levenshtein: Using Abbreviations and Spellchecked Inputs in Ruby</title><description>&lt;p&gt;I have been spending a lot of time writing Ruby programs that take in data through the terminal. One of the problems is that mis-spelling something can cause the program to crash, and I want to be as quick as possible when doing data entry.&lt;/p&gt;
&lt;p&gt;One of my programs asks which server environment I would like to use before I start messing with any data (&lt;em&gt;development, integration, staging, production&lt;/em&gt;). It would be great if all of the following abbreviations or misspellings would choose the development environment, and keep the program rolling:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;dev&lt;/li&gt;
&lt;li&gt;development&lt;/li&gt;
&lt;li&gt;devel&lt;/li&gt;
&lt;li&gt;deevleopmnt&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;You get the idea- abbreviations and spellchecking from known inputs. To accomplish this I leverage the Levenshtein distance algorithm, more commonly known as &amp;#8220;edit distance&amp;#8221;. This algorithm compares two strings and returns an integer that is equal to the amount of edits needed to transform the first string into the second.&lt;/p&gt;
&lt;p&gt;Here is the &lt;a href="https://gist.github.com/3152509" title="Github Gist" target="_blank"&gt;Github Gist for Lazy Levenshtein&lt;/a&gt;, with the sample code below so we can dig through it.&lt;/p&gt;
&lt;pre class="prettyprint"&gt;# test by running:
# ruby lazy.rb
# use control+c to exit
require 'amatch'
include Amatch

def lazy input, matches, abbreviations=true
  # setup the Levenshtein comparator
  distances = {}
  m = Levenshtein.new(input)
  matches.reverse.each do |match|
    # get the edit distance
    tests = []
    tests &amp;lt;&amp;lt; m.match(match)
    tests &amp;lt;&amp;lt; m.match(match[0..3]) if abbreviations
    
    # lowest score gets placed
    distances[tests.min] = match
  end
  # return input, returns original if matches is empty
  input = distances.empty? ? input : distances.min.last
end

environments = %w(development integration staging production)
while true
  puts "\nenvironments #{environments.join(', ')}"  
  print "choose environment: "
  input = gets.chomp
  puts "match: #{lazy(input, environments)}"
end
&lt;/pre&gt;
&lt;p&gt;The three parameters are the input itself, an array of possible matches, and a boolean that tells the method whether or not you want to match abbreviations. The method sets up a Levenshtein comparison for each potential match (using the &lt;a href="http://flori.github.com/amatch/doc/index.html" title="Ruby Amatch" target="_blank"&gt;Ruby Amatch library&lt;/a&gt;), and scores the comparison. We are playing golf here, because the lowest score wins the game!&lt;/p&gt;
&lt;p&gt;The method also reverses the array in the main loop, which puts priority to the first items in the array if there happens to be a tie between matches. Unlike typical &amp;#8220;spellcheck&amp;#8221;, this method will never return &amp;#8220;not found&amp;#8221;, it will &lt;em&gt;always&lt;/em&gt; return a match, and if the &amp;#8220;matches&amp;#8221; array is empty, it simply returns the provided input.&lt;/p&gt;
&lt;p&gt;This has helped me make inputting much faster with smarter defaults, and given me the piece of mind that my misspellings will always turn into known/safe values.&lt;/p&gt;</description><link>http://bytesofpi.com/post/27642025849</link><guid>http://bytesofpi.com/post/27642025849</guid><pubDate>Fri, 20 Jul 2012 15:07:00 -0400</pubDate><category>ruby</category><category>levenshtein</category><category>spellcheck</category><category>abbreviation</category><category>data entry</category><category>terminal</category></item><item><title>Article Analysis: Matching People's Names to Email Addresses</title><description>&lt;p&gt;&lt;small&gt;*code examples are based in ruby&lt;/small&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Consider you are scraping web articles building a list of contacts for a PR company. Getting email addresses is as simple as a regular expression.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;string = 'John Smith can be contacted at john.smith@gmail.com'
emails = []
string.scan(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}/i).each {|x| emails &amp;lt;&amp;lt; x}
&lt;/pre&gt;
&lt;p&gt;However, an email address is only so powerful, it would be really great if we could match a name to that email address. The problem statement is pretty simple- match email addresses in the article to the names in the article.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finding names&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So if you are thinking that finding names in text can&amp;#8217;t be that hard, lets take a stroll down that dark alley really quick. Maybe just a regular expression that matches two capitalized strings in a row could do the trick.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;/([A-Z]+[a-zA-Z]*)\s+([A-Z]+[a-zA-Z]*)/
&lt;/pre&gt;
&lt;p&gt;Well, that&amp;#8217;s cool, but what if there is a middle name, or even worse, an abbreviated name? So now, we add an optional third string to the regular expression, and allow for abbreviations.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;/([A-Z]+[a-zA-Z.]*)\s+([A-Z]+[a-zA-Z.]*)+(\s+([A-Z]+[a-zA-Z]*))?/
&lt;/pre&gt;
&lt;p&gt;This is looking great, and then you hit a name like Michael D&amp;#8217;hunt, or De&amp;#8217;Angelo Munez. Okay, so now we allow some apostrophes.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;/([A-Z']+[a-zA-Z'.]+)\s+([A-Z]+[a-zA-Z'.]*)+(\s+([A-Z']+[a-zA-Z']*))?/
&lt;/pre&gt;
&lt;p&gt;So right now, you run this against a list of 10,000 common names, and a boatload of Lorum Ipsum, and you have some great accuracy. However, in the real world you get a sentence like this, &amp;#8220;And Will Smith was not alone, he included his wife Jada on his trip to San Francisco, where they stayed at Hotel Palomar&amp;#8221;. Your regular expression just got roasted in so many ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Natural Language Processing (NPL)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;To parse out things like names, places, dates, and going into things like differentiating languages within text, we have to get a little more fancy. Natural language processing concerns itself with the study of linguistics, using a mixture of machine learning, statistics, and artificial intelligence to provide a meaningful analysis of human languages. For all intensive purposes, we can say that it breaks apart sentences so we can interpret them better using a computer.&lt;/p&gt;
&lt;p&gt;This is the crucial link between knowing if &amp;#8216;San Francisco&amp;#8217; is a person&amp;#8217;s name, or a physical place. The &lt;a href="http://nlp.stanford.edu/index.shtml" title="Stanford Natural Language Processing Group" target="_blank"&gt;Stanford Natural Language Processing Group&lt;/a&gt; has a set of &lt;a href="http://nlp.stanford.edu/software/corenlp.shtml" title="core open-source tools" target="_blank"&gt;core open-source tools&lt;/a&gt; that can take care of some of this by implementing known language patterns, and using massive libraries of common naming schemes for people, places, and things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Finding names, the right way&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;By implementing the Stanford CoreNLP Toolset, we can essentially throw some text at it, and with a couple filters we can have a list of names contained within the text. So from the sentence above, we may get a result like this.  &lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;[  
  {
    :name =&amp;gt; "Will",
    :start =&amp;gt; 4,
    :end =&amp;gt; 8
  },
  {
    :name =&amp;gt; "Smith",
    :start =&amp;gt; 9,
    :end =&amp;gt; 14
  },
  {
    :name =&amp;gt; "Jada",
    :start =&amp;gt; 51,
    :end =&amp;gt; 55
  }
]
&lt;/pre&gt;
&lt;p&gt;The &amp;#8216;start&amp;#8217; and &amp;#8216;end&amp;#8217; numbers refer to the string position of the name itself, and with a little magic it is possible to concatenate names if they appear together, giving a final result as follows.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;["Will Smith", "Jada"]
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Names to emails&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This matching problem is quite problematic considering the format that an article or piece of text might come in. In a perfect world, a person&amp;#8217;s name would appear right next to their email address.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;'John Smith can be contacted at john.smith@gmail.com, and Jill Ruth can be contacted at jill.ruth@gmail.com.'
&lt;/pre&gt;
&lt;p&gt;If we know the position of the name, and know the position of the email address, this is no problem- we just write a routine to find the closest email to the persons name. However this breaks down pretty quickly.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;'John Smith and Jill Ruth can be contacted respectively at john.smith@gmail.com, and jill.ruth@gmail.com.'
&lt;/pre&gt;
&lt;p&gt;Or even worse&amp;#8230;&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;'Article written by Edward Jones

... article body ...

Contact the writer at ejones@gmail.com'
&lt;/pre&gt;
&lt;p&gt;The article body itself could also contain important names and email addresses as well, scattered as they please, so this calls for some more advanced parsing techniques.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Levenshtein distance&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My take on this problem is that we can throw name-position vs. email-position out the window; it is not reliable. The one thing we can rely on is that, in most professional situations, a person&amp;#8217;s email has some reference to their name. &lt;/p&gt;
&lt;p&gt;This is where the &lt;a href="http://en.wikipedia.org/wiki/Levenshtein_distance" title="Levenshtein distance algorithm" target="_blank"&gt;Levenshtein distance algorithm&lt;/a&gt; comes in- it calculates the numbers of edits needed to transform one string into another. In our case, we are comparing a persons name to their email. It quickly becomes apparent that the email extension and any numbers can be removed from the email address, and normalizing the case is helpful before making the comparisons. Let&amp;#8217;s looks at some results for John Smith (or more specifically in lower case, &amp;#8220;john smith&amp;#8221;).&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;john.smith@gmail.com -&amp;gt; john.smith : 1 edit
j.smith123@gmail.com -&amp;gt; j.smith : 4 edits
john.walker.smith@gmail.com -&amp;gt; john.walker.smith : 8 edits
jwsmith@gmail.com -&amp;gt; jwsmith : 4 edits
jws3319@gmail.com -&amp;gt; jws : 8 edits
&lt;/pre&gt;
&lt;p&gt;So that is pretty neat, and the next step to the problem is pretty clear- we need to test a bunch of common email address patterns against the persons name, and use the best score. So instead of making comparisons with just &amp;#8220;john smith&amp;#8221;, we can abstract the name into some common formats.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;person = "John Smith"
email = "jsmith44@gmail.com"

# remove the email extension and everything besides characters
m = Levenshtein.new(email.split('@').first.downcase.scan(/[a-z]/).join(''))

# run a standard set of tests against the persons name
tests = []
tests &amp;lt;&amp;lt; m.match(person.downcase.scan(/[a-z]/).join('')) 
tests &amp;lt;&amp;lt; m.match("#{person.split(' ').first.downcase[0]}#{person.split(' ').last.downcase[0]}")
tests &amp;lt;&amp;lt; m.match(person.split(' ').first.downcase)
tests &amp;lt;&amp;lt; m.match(person.split(' ').last.downcase)
...

best_result = tests.min
&lt;/pre&gt;
&lt;p&gt;If this is run for every person and every email address found in an article, it will provide the best score for each person vs. email address.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Scores into results&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With any type of artificial intelligence, there is rarely a concept of &amp;#8220;passing a test&amp;#8221;, there are only various levels of failure. The goal is to simply minimize failure in the best way possible, and developing with any other intention can be a destructive process. Using our scores from the previous step, we attempt to award all the emails we found to the person most deserving. Consider the following sample set.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;people = ["Matt Gaidica", "Brad Birdsall", "John Smith", "Grant Olidapo", "Minh Nguyen"]
emails = ["mattyg@gmail.com", "bradbirdman17@gmail.com", "grant.olidapo@gmail.com", "mn1@gmail.com"]&lt;/pre&gt;
&lt;p&gt;The scores we produced account for every name vs. every email, or 20 (5x4) unique values. We look to some sort of complexity reduction algorithm to reduce this set of 20 data points, to only 4, which directly relate names to emails, leaving one of our people email-less. After about 20 lines of magic, our algorithm spits out the results.&lt;/p&gt;
&lt;pre class="prettyprint lang-ruby"&gt;{
  "Matt Gaidica" =&amp;gt; "mattg@gmail.com",
  "Brad Birdsall" =&amp;gt; "bradbirdman17@gmail.com",
  "Grant Olidapo" =&amp;gt; "grant.olidapo@gmail.com",
  "Minh Nguyen" =&amp;gt; "mn1@gmail.com"
}
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Tip of the iceberg&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I look at this as just one of the ways to accomplish this goal. This process can be heavily supplemented with machine learning techniques to produce better name recognition, and further develop common email address patterns for your specific type of article, document, or data set.&lt;/p&gt;
&lt;p&gt;I have opened a library on Github called &lt;a href="https://github.com/mattgaidica/textract" title="Textract" target="_blank"&gt;Textract&lt;/a&gt;, which includes the code for this entire process. My goal is to keep the problems simple, and the solutions simpler.&lt;/p&gt;</description><link>http://bytesofpi.com/post/27118350467</link><guid>http://bytesofpi.com/post/27118350467</guid><pubDate>Fri, 13 Jul 2012 07:36:00 -0400</pubDate><category>language</category><category>processing</category><category>machine learning</category><category>ruby</category><category>textract</category></item><item><title>A Ruby wrapper for the (new) Basecamp API</title><description>&lt;a href="https://github.com/mattgaidica/basecamp-wrap"&gt;A Ruby wrapper for the (new) Basecamp API&lt;/a&gt;: &lt;p&gt;This is about as structurally simple as it could get to interact with the new Basecamp API (using HTTParty for the RESTful stuff). Very few endpoints are supported right now, but this might help you get going.&lt;/p&gt;</description><link>http://bytesofpi.com/post/27070244808</link><guid>http://bytesofpi.com/post/27070244808</guid><pubDate>Thu, 12 Jul 2012 16:14:00 -0400</pubDate><category>ruby</category><category>basecamp</category><category>api</category><category>httparty</category><category>REST</category></item><item><title>Exporting to CSV on Mac's Excel using PHP's fgetcsv</title><description>&lt;p&gt;PHP has a nice way of working with CSV files using the &lt;a href="http://php.net/manual/en/function.fgetcsv.php" title="fgetcsv" target="_blank"&gt;fgetcsv&lt;/a&gt; function. One of the downfalls in using the CSV format is dealing with &lt;a href="http://www.codinghorror.com/blog/2010/01/the-great-newline-schism.html" title="The Great Newline Schism" target="_blank"&gt;what character is used for new lines&lt;/a&gt;, which is how nearly all CSV files determine the separation of rows.&lt;/p&gt;
&lt;p&gt;If you are using excel on Mac and do not want to set your own newline character in PHP (or don&amp;#8217;t have access to it!), when you save the file, choose &lt;em&gt;Windows Comma Seperated (.csv) &lt;/em&gt;as the file type.&lt;/p&gt;</description><link>http://bytesofpi.com/post/27034047851</link><guid>http://bytesofpi.com/post/27034047851</guid><pubDate>Thu, 12 Jul 2012 01:31:00 -0400</pubDate><category>php</category><category>mac</category><category>excel</category><category>export</category><category>csv</category></item><item><title>The Stanford Natural Language Processing Group</title><description>&lt;a href="http://nlp.stanford.edu/software/corenlp.shtml"&gt;The Stanford Natural Language Processing Group&lt;/a&gt;</description><link>http://bytesofpi.com/post/26969549470</link><guid>http://bytesofpi.com/post/26969549470</guid><pubDate>Wed, 11 Jul 2012 05:30:00 -0400</pubDate><category>language</category><category>processing</category><category>machine learning</category></item><item><title>String to Boolean in Ruby</title><description>&lt;a href="http://jeffgardner.org/2011/08/04/rails-string-to-boolean-method/"&gt;String to Boolean in Ruby&lt;/a&gt;: &lt;p&gt;A great couple of lines that add a `to_bool` method to the Ruby String class. This is really helpful when passing in boolean values from a query string (like in an API). Just put this in a file and require it!&lt;/p&gt;</description><link>http://bytesofpi.com/post/26672588651</link><guid>http://bytesofpi.com/post/26672588651</guid><pubDate>Fri, 06 Jul 2012 22:59:00 -0400</pubDate><category>string</category><category>boolean</category><category>ruby</category></item><item><title>rspec_helper.rb for Rspec in Ruby</title><description>&lt;p&gt;&lt;pre class="prettyprint lang-ruby"&gt;require File.join(File.dirname(__FILE__), '..', 'app.rb')
require 'rack/test'

set :environment, :test
set :run, false
set :raise_errors, true
set :logging, false

def access_token
  "xxxxx"
end

def api_token
  "xxxxx"
end

def app
  Sinatra::Application
end

RSpec.configure do |config|
  config.include Rack::Test::Methods
end

#no database debug messages
ActiveRecord::Base.logger.level = Logger::INFO
&lt;/pre&gt;&lt;/p&gt;</description><link>http://bytesofpi.com/post/25473525452</link><guid>http://bytesofpi.com/post/25473525452</guid><pubDate>Tue, 19 Jun 2012 21:22:00 -0400</pubDate></item></channel></rss>
