<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <title>Collective Idea Blog</title>
  
  <link href="http://collectiveidea.com/blog/" />
  <id>4b57a16edabe9d744d000001</id>
  <updated>2012-02-07T10:36:46-05:00</updated>
 
  
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/collectiveidea" /><feedburner:info uri="collectiveidea" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
      <title>CoffeeScript Routing, part deux</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/NtePZE-76Nk/" />
      <id>4f2079efdabe9d4a3100a808</id>
      <updated>2012-02-07T10:36:46-05:00</updated>
      <published>2012-02-07T09:00:00-05:00</published>
      <content type="html">&lt;p&gt;I wrote a post not to long ago on how to roll your own &lt;a href="http://collectiveidea.com/blog/archives/2012/01/25/standalone-javascript-routing/"&gt;JavaScript router&lt;/a&gt;.  Our first version had named parameters, but we didn&amp;#8217;t use them at all when calling the callbacks.  Remembering the index of each parameter is a pain, so we&amp;#8217;re going to fix that.&lt;/p&gt;
&lt;p&gt;First things first, lets take a look at what we want to happen.  Given the following route:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;Route.add "/blog/:year/:month/:day", callbackMethod&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
We want the url &lt;code&gt;http://www.example.com/blog/2012/02/07&lt;/code&gt; to pass the following object to the callback:&lt;br /&gt;
&lt;pre class="javascript"&gt;&lt;code&gt;{
  year: 2012,
  month: 02,
  day:07
}&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;h2&gt;Make it happen!&lt;/h2&gt;
&lt;p&gt;The first thing we need is a list of the named parameters in the route.  We can get these by a using a simple regular expression before we process the route into a regular expression.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;parameterNames = path.match(/:(\w*)/g)&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Since this can, and should, differ wildly from route to route, we store those names on the same object that the route is on.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;{
  params: path.match(/:(\w*)/g),
}&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Now that we have the names of the parameters, we build a new &lt;code&gt;params&lt;/code&gt; object to pass back to the callback&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;index = 1
params = {}
for name in route.params
  params[name.slice(1)] = matches[index++]
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The resulting class now looks like this:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;class Router
  clearRoutes: -&amp;gt;
    @routes = []
  @process: -&amp;gt;
    for route in @routes
      matches = window.location.pathname.match(route.path)
      if matches?
        index = 1
        params = {}
        for name in route.params
          params[name.slice(1)] = matches[index++]
        route.callback(params)
        return
  @add: (path, callback) -&amp;gt;
    @routes ||= []
    @routes.push { 
      params: path.match(/:(\w*)/g),
      path: new RegExp(path.replace(/\//g, "\\/").replace(/:(\w*)(?!(\w))/g, "(\\w*)")), 
      callback: callback 
    }&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;There you have it.  A CoffeeScript stand alone router with named parameters.  I&amp;#8217;ve uploaded the resulting class along with its &lt;a href="http://pivotal.github.com/jasmine/"&gt;Jasmine&lt;/a&gt; tests to &lt;a href="https://github.com/tbugai/coffeescript-router"&gt;http://github.com/tbugai/coffeescript-router&lt;/a&gt;.  For those of you in the ruby world, its also available as the &lt;a href="https://rubygems.org/gems/coffeescript-router"&gt;coffeescript-router&lt;/a&gt; gem.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/NtePZE-76Nk" height="1" width="1"/&gt;</content>
      <author>
        <name>Tim Bugai</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/02/07/coffeescript-routing-part-deux/</feedburner:origLink></entry>
  
    <entry>
      <title>Testing File Downloads with Capybara and ChromeDriver</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/N4tbfBYs88I/" />
      <id>4f22b2ccdabe9d281b00a7ef</id>
      <updated>2012-01-30T12:25:55-05:00</updated>
      <published>2012-01-27T09:00:00-05:00</published>
      <content type="html">&lt;p&gt;At Collective Idea, we &lt;abbr title="love"&gt;♥&lt;/abbr&gt; Cucumber, Capybara and ChromeDriver… and alliteration. But we recently encountered an issue with a very Ajaxy Rails app where we need to test a file download and assert its content.&lt;/p&gt;
&lt;p&gt;Our scenario looks like:&lt;/p&gt;
&lt;pre&gt;
Scenario: Exporting the fruits list
  Given the following fruits exist:
    | Name   | Color  |
    | Apple  | Red    |
    | Orange | Orange |
    | Lemon  | Yellow |
  And I am on the fruits page
  When I follow "Export"
  Then the downloaded file content should be:
    """
    Name,Color
    Apple,Red
    Orange,Orange
    Lemon,Yellow
    """
&lt;/pre&gt;
&lt;p&gt;Easy enough! Early in the app&amp;#8217;s life, we wrote this Cucumber step:&lt;/p&gt;
&lt;pre&gt;
Then "the downloaded file content should be:" do |content|
  page.response_headers["Content-Disposition"].should == "attachment"
  page.source.should == content
end
&lt;/pre&gt;
&lt;p&gt;This worked like gangbusters. But with such an Ajaxy app, we soon moved to ChromeDriver as our default Capybara driver and our nice green scenario turned an annoying shade of red.&lt;/p&gt;
&lt;p&gt;When the scenario ran, Chrome triggered the download as expected but threw the file into my &amp;#8220;Downloads&amp;#8221; directory. Capybara had no reference to its content and to make matters worse, Cucumber didn&amp;#8217;t wait for the download to finish before moving on.&lt;/p&gt;
&lt;h2&gt;After much frustration…&lt;/h2&gt;
&lt;p&gt;We discovered that it&amp;#8217;s possible to provide a Chrome profile (just a collection of settings) when registering the &lt;code&gt;:chrome&lt;/code&gt; Capybara driver. We&amp;#8217;re registering the driver in &lt;code&gt;features/support/chromedriver.rb&lt;/code&gt; so we added the profile there:&lt;/p&gt;
&lt;pre&gt;
require "selenium/webdriver"

Capybara.register_driver :chrome do |app|
  profile = Selenium::WebDriver::Chrome::Profile.new
  profile["download.default_directory"] = DownloadHelpers::PATH.to_s
  Capybara::Selenium::Driver.new(app, :browser =&amp;gt; :chrome, :profile =&amp;gt; profile)
end

Capybara.default_driver = Capybara.javascript_driver = :chrome
&lt;/pre&gt;
&lt;p&gt;We added a &lt;code&gt;download.default_directory&lt;/code&gt; setting to the profile. This tells the browser where to send downloaded files. Eureka!&lt;/p&gt;
&lt;p&gt;That answers the question of downloading the file to the proper place, but we still need to make sure we wait for the download to finish. We take care of that in &lt;code&gt;features/support/downloads.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;
module DownloadHelpers
  TIMEOUT = 10
  PATH    = Rails.root.join("tmp/downloads")

  extend self

  def downloads
    Dir[PATH.join("*")]
  end

  def download
    downloads.first
  end

  def download_content
    wait_for_download
    File.read(download)
  end

  def wait_for_download
    Timeout.timeout(TIMEOUT) do
      sleep 0.1 until downloaded?
    end
  end

  def downloaded?
    !downloading? &amp;amp;&amp;amp; downloads.any?
  end

  def downloading?
    downloads.grep(/\.crdownload$/).any?
  end

  def clear_downloads
    FileUtils.rm_f(downloads)
  end
end

World(DownloadsHelpers)

Before do
  clear_downloads
end

After do
  clear_downloads
end
&lt;/pre&gt;
&lt;p&gt;Now we&amp;#8217;re equipped with everything we need to effectively manage and inspect file downloads. Our Cucumber step simply changes to:&lt;/p&gt;
&lt;pre&gt;
Then "the downloaded file content should be:" do |content|
  download_content.should == content
end
&lt;/pre&gt;
&lt;p&gt;And there you have it. It&amp;#8217;s a little bit of added support code but if you&amp;#8217;re dealing with downloads, it&amp;#8217;s well worth your while.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/N4tbfBYs88I" height="1" width="1"/&gt;</content>
      <author>
        <name>Steve Richert</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/27/testing-file-downloads-with-capybara-and-chromedriver/</feedburner:origLink></entry>
  
    <entry>
      <title>Standalone Javascript Routing</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/0cVrd9s-mPw/" />
      <id>4f2009a7dabe9d0ed500156f</id>
      <updated>2012-01-25T14:34:19-05:00</updated>
      <published>2012-01-25T12:00:00-05:00</published>
      <content type="html">&lt;p&gt;A recent project has us using &lt;a href="http://spinejs.com"&gt;spine.js&lt;/a&gt; as well as a few other JavaScript libraries.  Though spine.js comes with its &lt;a href="http://spinejs.com/docs/routing"&gt;own routing&lt;/a&gt;, it conflicts with &lt;a href="https://github.com/defunkt/jquery-pjax"&gt;pjax&lt;/a&gt;.  The solution was to roll our own.&lt;/p&gt;
&lt;p&gt;The requirements are simple, we should be able to give it a set of routes and their corresponding callbacks and we should be able to process the browsers url upon request.  The CoffeeScript for that looks like this:&lt;br /&gt;
&lt;pre class="javascript"&gt;&lt;code&gt;class Router
  @add: (path, callback) -&amp;gt;
    @routes ||= []
    @routes.push { 
      path: path, 
      callback: callback 
    }
  @process: -&amp;gt;
    for route in @routes
      params = window.location.pathname.match(route.path)
      if params?
        route.callback(params)
        return&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This code works exactly as we want it too, but there are a few things I&amp;#8217;d like to make better.  The first of which is that we have to provide a regex as the path so our routes would look something like this:&lt;br /&gt;
&lt;pre&gt;Route.add /\/blog\/(\w*)/, blogCallback&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;It would be much easier to read and maintain if it followed more of a rails-routing-style semantic like this:&lt;br /&gt;
&lt;pre&gt;Route.add &amp;#8220;/blog/:id&amp;#8221;, blogCallback&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;We can make this possible by processing the path string into its regex counterpart inside &lt;code&gt;Route.add()&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;The first thing we need to do is escape the forward slashes ( / )&lt;br /&gt;
&lt;pre&gt;path.replace(/\//g, &amp;#8220;\\/&amp;#8221;)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then we need to change everything starting with a colon into a capture field&lt;br /&gt;
&lt;pre&gt;path.replace(/:(\w*)(?!(\w))/g,&amp;#8220;(\\w*)&amp;#8221;)&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;And then we convert the fancied up string into a RegExp and save it as the path for our route.  I&amp;#8217;ve chained all of the &lt;code&gt;replaces()&lt;/code&gt; together for simplicity.&lt;br /&gt;
&lt;pre&gt;path = new RegExp(path.replace(/\//g, &amp;#8220;\\/&amp;#8221;).replace(/:(\w*)/g,&amp;#8220;(\\w*)&amp;#8221;))&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;(thanks to Jonathan Castello for pointing out we were being too cautious with the last regex)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The updated class looks like this:&lt;br /&gt;
&lt;pre class="javascript"&gt;&lt;code&gt;class Router
  @add: (path, callback) -&amp;gt;
    @routes ||= []
    @routes.push { 
      path: new RegExp(path.replace(/\//g, "\\/").replace(/:(\w*)/g,"(\\w*)")), 
      callback: callback 
    }  
  @process: -&amp;gt;
    for route in @routes
      params = window.location.pathname.match(route.path)
      if params?
        route.callback(params)
        return&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Then in our project, we have the following setup code.&lt;br /&gt;
&lt;pre class="javascript"&gt;&lt;code&gt;$ -&amp;gt;
  Route.add "/blog/:id", blogCallback
  $(document).on "ready end.pjax", -&amp;gt;
    Route.process()&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Whenever our document is ready or a pjax link has completed, our routes get matched against the url and the appropriate callback gets fired.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/0cVrd9s-mPw" height="1" width="1"/&gt;</content>
      <author>
        <name>Tim Bugai</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/25/standalone-javascript-routing/</feedburner:origLink></entry>
  
    <entry>
      <title>Slow it Down</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/EnuY5Ac-Tl0/" />
      <id>4f15f0e2dabe9d087f0597d8</id>
      <updated>2012-01-18T11:13:56-05:00</updated>
      <published>2012-01-18T11:00:00-05:00</published>
      <content type="html">&lt;p&gt;Most of the time, you test your apps on a fast connection, especially when working on a local machine. Most of your clients/visitors/customers aren&amp;#8217;t so lucky, but how do you simulate their connection speed?&lt;/p&gt;
&lt;p&gt;If you have installed Xcode on Lion, you have access to a very cool tool called Network Link Conditioner&lt;sup class="footnote"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/4f15ee6fdabe9d3210007deb/network_link_conditioner.png" width=425&gt;&lt;/p&gt;
&lt;p&gt;It is a preference pane, but not installed by default. You&amp;#8217;ll find it in &lt;code&gt;/Developer/Applications/Utilities/Network Link Conditioner/&lt;/code&gt; Simply double-click the prefPane and it will install itself.&lt;/p&gt;
&lt;p&gt;Once enabled, you can set your network to simulate everything from 3G or Edge to typical &lt;span class="caps"&gt;DSL&lt;/span&gt;. You can even set your own profile to tweak the settings. It works at the network level, so it affects your entire system. No proxies or any other setup needed!&lt;/p&gt;
&lt;p&gt;As an example, we have an app in development where we know the users will have high latency. Instead of just hoping they get better connections, we can simulate their situation and test it out, &lt;strong&gt;even when we&amp;#8217;re using Rails on our laptops&lt;/strong&gt;. We&amp;#8217;re then using it to optimize to their situation, not just blindly&lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Give it a shot and see how your sites fare.&lt;/p&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; This may win the award for ugliest Apple icon. Please prove me wrong!&lt;/p&gt;
&lt;p class="footnote" id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; Don&amp;#8217;t prematurely optimize. That&amp;#8217;s still bad.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/EnuY5Ac-Tl0" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/18/slow-it-down/</feedburner:origLink></entry>
  
    <entry>
      <title>Refactored for Efficiency </title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/kbNdLIh6UrY/" />
      <id>4ef0bbf2dabe9d3f2602dfec</id>
      <updated>2012-01-17T10:15:02-05:00</updated>
      <published>2012-01-17T09:00:00-05:00</published>
      <content type="html">&lt;p&gt;Refactoring your code is for more then keeping it &lt;span class="caps"&gt;DRY&lt;/span&gt;.  It also gives you a chance to make it more efficient.&lt;/p&gt;
&lt;p&gt;Take a look at the following Objective-C.  Its goal is to return the full path to a sessions folder which is a subdirectory in the users documents directory.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;
-(NSString *)filePath {
    NSString *baseDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    NSString *sessionPath = [baseDirectory stringByAppendingPathComponent:self.sessionName];
    return [sessionPath stringByAppendingPathComponent:self.fileName];   
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It accomplishes its task but is relatively expensive.  There are two string concatenations, each of which involve another allocation of memory.&lt;/p&gt;
&lt;p&gt;We can speed this up a bit by rewritting it like this:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
-(NSString *)filePath {
    return [NSString stringWithFormat:@"%@/%@/%@",
         [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0], 
         self.sessionName, 
         self.fileName
    ]; 
}
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
The new method causes only one memory allocation and one string concatenation.  Thats half of what our first attempt required.&lt;/p&gt;
&lt;p&gt;We can also cache the result as it doesn&amp;#8217;t change during its session.   We simply add a &lt;code&gt;NSString *_filePath&lt;/code&gt; to the containing class and refactor further.&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;
-(NSString *)filePath {
    if(_filePath == null) {   
        _filePath = [NSString stringWithFormat:@"%@/%@/%@",
             [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0], 
             self.sessionName, 
             self.fileName
        ]; 
    }
    return _filePath;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;The end result is a method that is twice is fast the first time it is called and even more so each additional call due to memoization.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/kbNdLIh6UrY" height="1" width="1"/&gt;</content>
      <author>
        <name>Tim Bugai</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/17/refactored-for-efficiency/</feedburner:origLink></entry>
  
    <entry>
      <title>Give pry a Try</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/IGrngD7fbyw/" />
      <id>4f147c89dabe9d451400e4fb</id>
      <updated>2012-01-17T09:27:25-05:00</updated>
      <published>2012-01-16T14:00:00-05:00</published>
      <content type="html">&lt;p&gt;One of the things holding us back from developing on Ruby 1.9.3 has been ruby-debug. There are issues with installing and running it, and while they are manageable, it makes it such that (on a Rails projects with a Gemfile) every user needs to then use 1.9.3 and the unreleased ruby-debug19 version. Not fun.&lt;/p&gt;
&lt;p&gt;So after many people suggested we try it, we gave &lt;a href="http://pry.github.com/"&gt;pry&lt;/a&gt; a shot. I don&amp;#8217;t know why we didn&amp;#8217;t before; it is quick, easy, and allows a wide range of Ruby versions.&lt;/p&gt;
&lt;p&gt;On a Rails project, your install is simple. In your &lt;code&gt;Gemfile&lt;/code&gt; remove anything related to &lt;code&gt;ruby-debug&lt;/code&gt; and add in &lt;code&gt;pry&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;group :development, :test do
  gem "pry"
end&lt;/pre&gt;
&lt;p&gt;Then, anywhere you previously used &lt;code&gt;debugger&lt;/code&gt; use &lt;code&gt;pry&lt;/code&gt; instead.&lt;/p&gt;
&lt;p&gt;For example, we frequently have a cucumber step for invoking the debugger:&lt;/p&gt;
&lt;pre class="ruby"&gt;When 'I debug' do
  pry
end&lt;/pre&gt;
&lt;p&gt;It is a little different from ruby-debug, but we&amp;#8217;re loving it so far!&lt;/p&gt;
&lt;p&gt;&lt;ins&gt;Update: banisterfiend points out in the comments:&lt;/ins&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you use `binding.pry` instead of just `pry` you&amp;#8217;ll get access to all the locals at the point you call it, too :)&lt;/p&gt;
&lt;/blockquote&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/IGrngD7fbyw" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/16/give-pry-a-try/</feedburner:origLink></entry>
  
    <entry>
      <title>Welcome Ryan Glover</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/8Mdqzxz1rEQ/" />
      <id>4f0af1d8dabe9d3aaf01dbf2</id>
      <updated>2012-01-09T13:10:19-05:00</updated>
      <published>2012-01-09T08:55:00-05:00</published>
      <content type="html">&lt;p&gt;We&amp;#8217;re thrilled to welcome &lt;a href="/about/#ryan"&gt;Ryan Glover&lt;/a&gt; to the team. Ryan comes to us from the scary world of government contracting, complete with the &lt;a href="http://en.wikipedia.org/wiki/Security_clearance#Compartmented_Information"&gt;highest U.S. government clearance&lt;/a&gt; available. We think he might be a spy, but we&amp;#8217;re ok with that.&lt;/p&gt;
&lt;p&gt;Ryan is a Michigan native currently living in Maryland. Though after his stint learning Mandarin in the Air Force, he&amp;#8217;d probably be comfortable anywhere in the world.&lt;/p&gt;
&lt;p&gt;Online you can find him on &lt;a href="http://github.com/ersatzryan"&gt;GitHub&lt;/a&gt; or &lt;a href="http://twitter.com/ersatzryan"&gt;Twitter&lt;/a&gt; as @ersatzryan. We first met Ryan when he started forking some of our open source work. We loved his help and hope he continues.&lt;/p&gt;
&lt;p&gt;We&amp;#8217;re very excited to add Ryan to our team, so please give him a warm welcome!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/8Mdqzxz1rEQ" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/09/welcome-ryan-glover/</feedburner:origLink></entry>
  
    <entry>
      <title>Capybara, Cucumber and How the Cookie Crumbles</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/tUsRPFv_5lY/" />
      <id>4f023375dabe9d6644007889</id>
      <updated>2012-01-05T13:26:04-05:00</updated>
      <published>2012-01-05T13:00:00-05:00</published>
      <content type="html">&lt;p&gt;When I write a new Rails application, it often needs some sort of user authentication. I like to test authentication in Cucumber and a typical happy-path scenario might look like:&lt;/p&gt;
&lt;pre&gt;
Scenario: Happy path authentication
  Given the following user exists:
    | Email                    | Password |
    | steve@collectiveidea.com | secret   |
  When I go to the homepage
  Then I should see "Sign In"
  But I should not see "Sign Out"
  When I follow "Sign In"
  And I fill in the following:
    | Email    | steve@collectiveidea.com |
    | Password | secret                   |
  And I press "Continue"
  Then I should see "Sign Out"
  But I should not see "Sign In"
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll notice that the &lt;code&gt;Given&lt;/code&gt; step above requires no action from the user. Givens simply set the stage for the rest of the scenario.&lt;/p&gt;
&lt;p&gt;This will be important later.&lt;/p&gt;
&lt;h2&gt;Fast Forward…&lt;/h2&gt;
&lt;p&gt;So now that I have authentication working in my application, I&amp;#8217;d like to use it elsewhere in my Cucumber suite:&lt;/p&gt;
&lt;pre&gt;
Scenario: User email updation
  Given a user exists with an email of "steve@collectiveidea.com"
  And I am signed in as "steve@collectiveidea.com"
  When I go to the edit account page
  And I fill in "Email" with "steve@gemnasium.com"
  And I press "Save"
  Then I should be on the account page
  And I should see "steve@gemnasium.com"
  But I should not see "steve@collectiveidea.com"
&lt;/pre&gt;
&lt;p&gt;But how do I write the second step to sign in my user?&lt;/p&gt;
&lt;p&gt;Your first instinct may be to replicate the steps from our authentication scenario, but this can be a bad idea. After all, this is a &lt;code&gt;Given&lt;/code&gt;. All I want to do is set the stage. I&amp;#8217;ll be using this step quite a bit and the overhead of two additional requests can stack up quickly.&lt;/p&gt;
&lt;p&gt;What I really want to do is to set the set the signed-in user directly. Here&amp;#8217;s the &lt;code&gt;current_user&lt;/code&gt; helper method in my &lt;code&gt;ApplicationController&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;
def current_user
  return @current_user if defined?(@current_user)
  @current_user = cookies[:token] &amp;amp;&amp;amp; User.find_by_token(cookies[:token])
end
&lt;/pre&gt;
&lt;p&gt;And there inlies my answer… Let&amp;#8217;s just set the cookie!&lt;/p&gt;
&lt;pre class="ruby"&gt;
When /^I am signed in as "([^"]*)"$/ do |email|
  cookies[:token] = User.find_by_email!(email).token
end
&lt;/pre&gt;
&lt;p&gt;And in some cases, this works great. If you use only the Rack::Test driver and avoid permanent or signed cookies, you should be all set. But as soon as you need your authentication step in a JavaScript scenario, it all falls apart.&lt;/p&gt;
&lt;h2&gt;Putting the Pieces Together&lt;/h2&gt;
&lt;p&gt;Long story short: each Capybara driver handles its cookies differently. The cookies hash we access in our step is specific to Rack::Test and is actually a &lt;code&gt;Rack::Test::CookieJar&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;If you want your application cookies to Just Work™ from anywhere in your Cucumber suite, throw the following into &lt;code&gt;features/support/cookies.rb&lt;/code&gt;:&lt;/p&gt;
&lt;pre class="ruby"&gt;
module Capybara
  class Session
    def cookies
      @cookies ||= begin
        secret = Rails.application.config.secret_token
        cookies = ActionDispatch::Cookies::CookieJar.new(secret)
        cookies.stub(:close!)
        cookies
      end
    end
  end
end

Before do
  request = ActionDispatch::Request.any_instance
  request.stub(:cookie_jar).and_return{ page.cookies }
  request.stub(:cookies).and_return{ page.cookies }
end
&lt;/pre&gt;
&lt;p&gt;You&amp;#8217;ll need a stubbing library. I&amp;#8217;m using RSpec.&lt;/p&gt;
&lt;p&gt;This allows each of your Capybara sessions to keep its own separate set of cookies. And they&amp;#8217;re &lt;em&gt;real&lt;/em&gt; cookies, meaning that you can use &lt;code&gt;cookies.permananent&lt;/code&gt; and &lt;code&gt;cookies.signed&lt;/code&gt; just like you do in your controllers. Then, after each scenario, Capybara will clean its sessions, along with your cookies.&lt;/p&gt;
&lt;p&gt;Just use &lt;code&gt;page.cookies&lt;/code&gt; and you&amp;#8217;re good to go!&lt;/p&gt;
&lt;pre class="ruby"&gt;
When /^I am signed in as "([^"]*)"$/ do |email|
  page.cookies[:token] = User.find_by_email!(email).token
end
&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/tUsRPFv_5lY" height="1" width="1"/&gt;</content>
      <author>
        <name>Steve Richert</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/05/capybara-cucumber-and-how-the-cookie-crumbles/</feedburner:origLink></entry>
  
    <entry>
      <title>The Big Three-Oh</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/kYuJuh-I7Mg/" />
      <id>4f0207a2dabe9d419a013688</id>
      <updated>2012-01-04T09:31:19-05:00</updated>
      <published>2012-01-04T08:00:00-05:00</published>
      <content type="html">&lt;p&gt;&lt;a href="https://github.com/collectiveidea/delayed_job"&gt;Delayed Job&lt;/a&gt; turned 3 over the holidays. It&amp;#8217;s been a long time coming but it finally happened. A huge thanks goes out to &lt;a href="https://github.com/betamatt"&gt;betamatt&lt;/a&gt; for his contributions and help in maintaining this project over the past year, as well as &lt;a href="https://github.com/bernardelli"&gt;bernardelli&lt;/a&gt; for adding named queues. Thanks guys!&lt;/p&gt;
&lt;h2&gt;Changes&lt;/h2&gt;
&lt;p&gt;Here&amp;#8217;s a quick rundown of the changes. You can see &lt;a href="https://github.com/collectiveidea/delayed_job/compare/v2.1.4...v3.0.0"&gt;the full list on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;New&lt;/strong&gt;: Named queues [ &lt;a href="https://github.com/bernardelli"&gt;bernardelli&lt;/a&gt; ]&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;New&lt;/strong&gt;: Job/Worker lifecycle callbacks [ &lt;a href="https://github.com/betamatt"&gt;betamatt&lt;/a&gt; ]&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Change&lt;/strong&gt;: &lt;code&gt;daemons&lt;/code&gt; is no longer a runtime dependency&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Change&lt;/strong&gt;: Active Record backend support is provided by a separate gem&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Change&lt;/strong&gt;: Enqueue hook is called before jobs are saved so that they may be modified&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Problem deserializing models that use a custom primary key column&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Deserializing AR models when the object isn&amp;#8217;t in the default scope&lt;/li&gt;
	&lt;li&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Hooks not getting called when delay_jobs is false&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;DJ 3 introduces Resque-style named queues while still retaining DJ-style priority. The goal is to provide a system for grouping tasks to be worked by separate pools of workers.&lt;/p&gt;
&lt;p&gt;Jobs can be assigned to a queue by setting the &lt;code&gt;queue&lt;/code&gt; option:&lt;/p&gt;
&lt;pre class="ruby"&gt;&lt;code&gt;object.delay(:queue =&amp;gt; 'tracking').method
Delayed::Job.enqueue job, :queue =&amp;gt; 'tracking'
handle_asynchronously :tweet_later, :queue =&amp;gt; 'tweets'
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you&amp;#8217;re using &lt;code&gt;rake&lt;/code&gt;, you can work off those queues by setting the &lt;code&gt;QUEUE&lt;/code&gt; or &lt;code&gt;QUEUES&lt;/code&gt; environment variable. If you&amp;#8217;re using &lt;code&gt;daemons&lt;/code&gt;, set the &lt;code&gt;--queue&lt;/code&gt; or &lt;code&gt;--queues&lt;/code&gt; option.&lt;/p&gt;
&lt;pre class="ruby"&gt;&lt;code&gt;# with rake
$ QUEUE=tracking rake jobs:work
$ QUEUES=mailers,tasks rake jobs:work

# with daemons
$ RAILS_ENV=production delayed_job --queue=tracking start
$ RAILS_ENV=production delayed_job --queues=mailers,tasks start&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;DJ 3 no longer has &lt;code&gt;daemons&lt;/code&gt; as a runtime dependency. You&amp;#8217;ll need to add &lt;code&gt;gem 'daemons'&lt;/code&gt; to your Gemfile if you want to use &lt;code&gt;script/delayed_job&lt;/code&gt;. Check the &lt;a href="https://github.com/collectiveidea/delayed_job/commit/46533d64383bdec9ac0463c9d5e8a64f03f54d2c#comments"&gt;comments on the commit&lt;/a&gt; for further explanation.&lt;/p&gt;
&lt;p&gt;As always, feedback and patches are welcomed. :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/kYuJuh-I7Mg" height="1" width="1"/&gt;</content>
      <author>
        <name>Brian Ryckbost</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2012/01/04/the-big-three-oh/</feedburner:origLink></entry>
  
    <entry>
      <title>Type it Faster!</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/IvUsZ9JeZfg/" />
      <id>4ee29b69dabe9d62db005dac</id>
      <updated>2011-12-15T11:23:52-05:00</updated>
      <published>2011-12-15T11:00:00-05:00</published>
      <content type="html">&lt;p&gt;I frequently see developers using backspace to delete a few words and it takes &lt;strong&gt;forever&lt;/strong&gt; while they hold down the delete key. &lt;strong&gt;Please change your keyboard settings&lt;/strong&gt; so I don&amp;#8217;t have to suffer. You&amp;#8217;ll be happier too, I promise.&lt;/p&gt;
&lt;p&gt;&lt;img src="/assets/4ee29b1adabe9d62db005a39/keyboardsettings.png" style="width: 400px;"&gt;&lt;/p&gt;
&lt;p&gt;On your Mac, open System Preferences, then Keyboard. You want to crank the Key Repeat all the way to Fast. I keep Delay Until Repeat a step off Short, but try going all the way then backing down if you desire.&lt;/p&gt;
&lt;p&gt;Now go try holding down a key in an editor of your choice. Your life just got faster.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/IvUsZ9JeZfg" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/12/15/type-it-faster/</feedburner:origLink></entry>
  
    <entry>
      <title>Likes vs. Favorites</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/hTp0cGi0QlU/" />
      <id>4ed6df49dabe9d1b0700f37c</id>
      <updated>2011-11-30T21:52:13-05:00</updated>
      <published>2011-11-30T20:00:00-05:00</published>
      <content type="html">&lt;p&gt;It seems like everything is social today, and everyone has their own way of marking highlights. Facebook has the Like button, Twitter lets you Favorite tweets, Google has +1, etc. While all these are basically the same idea, I find that naming plays a big part in how I use them&lt;/p&gt;
&lt;p&gt;On Twitter and Flickr, where the term is &lt;strong&gt;Favorite&lt;/strong&gt;, I use them to make a curated list of things I might want to find later. My true favorites.&lt;/p&gt;
&lt;p&gt;Contrast that to Facebook and Instagram, where the term is &lt;strong&gt;Like&lt;/strong&gt;. Because it feels less committal, I find myself liking all sorts of things. Funny post? Cute picture of your kids? I&amp;#8217;ll Like that. It is more like a pat on the back instead of giving them an award, quicker and less permanent.&lt;/p&gt;
&lt;p&gt;When developing an app, for you or a client, think about the terms you use and how you want people to use the feature. I&amp;#8217;m sure other people don&amp;#8217;t over-think the Favorite button like I do, but some will. Use language to lead people where you want them to go.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/hTp0cGi0QlU" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/11/30/likes-vs-favorites/</feedburner:origLink></entry>
  
    <entry>
      <title>I am 9 programmer-years old</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/DosaQ9JZMWQ/" />
      <id>4eb15a79dabe9d49a6006a43</id>
      <updated>2011-11-02T11:36:30-04:00</updated>
      <published>2011-11-02T11:36:00-04:00</published>
      <content type="html">&lt;p&gt;I am about 9 years old in &amp;#8220;Programmer Years&amp;#8221;.  Like dog-years, the conversion from human-years to programmer-years is about 7&amp;#215;.  Thinking about a programmer development this way helps offer some lessons on growing into a fully mature developer (at about 18 programmer-years old).&lt;/p&gt;
&lt;p&gt;During my first year (in programmer-years) I couldn&amp;#8217;t really understand other programmer&amp;#8217;s words and often spent my evenings balled up in the fetal position crying.  This was a very frustrating couple of months.  There is really nothing to do here but force your way through it.  Light will come .&lt;/p&gt;
&lt;h2&gt;1-10 programmer-years old&lt;/h2&gt;
&lt;p&gt;I got so I could walk and then run, though not always running in the right direction.  I was often whiny when I needed help.  Other programmers raising me needed to be firm that sometimes I must solve my own problems.  It was very much like my 6 year old daughter who knows how to tie her shoes, but it takes her twice as long and doesn&amp;#8217;t turn out quite as well as when I do it for her. She is aware of this fact, so she whines and tries to con me to do it for her.  If your raising a programmer in this development phase, tough love can be useful, but maybe help your youngster get the preverbal knot out.&lt;/p&gt;
&lt;h2&gt;10-18 programmer-years old&lt;/h2&gt;
&lt;p&gt;This is likely to be the most fun phase of your developer life.  Latched onto a language as &amp;#8220;the golden hammer&amp;#8221;. You are confident that you can build just about anything.  You&amp;#8217;re adding new and more complex ideas every day and your confidence is running high.  Which is cause for some caution, as this will likely lead to a couple character building disasters.  Much like the 16 year old kid who&amp;#8217;s &amp;#8216;got this driving this down, man&amp;#8217; and then unwittingly drives his pickup truck straight into his girlfriend&amp;#8217;s parent&amp;#8217;s house while making-out with her (yes, that happened).  My only advice here would be to try to keep older programmers around through this phase of development to save you from yourself.&lt;/p&gt;
&lt;h2&gt;18-70 programmer-years old&lt;/h2&gt;
&lt;p&gt;You&amp;#8217;re a pro.  You&amp;#8217;re a teacher, open source contributor, and you will make big changes in the world.&lt;/p&gt;
&lt;h2&gt;70+&lt;/h2&gt;
&lt;p&gt;You can always pick out the 80 programmer-year old programmers as well.  They may have a full on neck beard, they are usually grumpy, surly and often act slightly crazy when responding to seemingly trivial things.&lt;/p&gt;
&lt;p&gt;Thinking about a programmers development this way has had a significant effect on how I learn.&lt;/p&gt;
&lt;p&gt;When we teach a 6-year-old math we don&amp;#8217;t hand them a math book starting with Addition, and ending in Differential Equations and say, &amp;#8220;when you finish, you&amp;#8217;ll know &amp;#8216;math&amp;#8217;.&amp;#8221;  Yet programmer books are not usually broken up in to &amp;#8220;Grades&amp;#8221;, so the inclination for newbies is to sit down with a Ruby book, for example, and &amp;#8216;learn&amp;#8217; Ruby.  A much more efficient and useful approach would be to have yourself surrounded with books for Ruby, Rails, &lt;span class="caps"&gt;SQL&lt;/span&gt;, jQuery, Unix, Python, Regular Expressions, HTML… (and others depending on what your focused on) and read the first quarter of all of them, then go on to the next quarter, much like a child in school learns a little math and science and a little geography in a particular grade, and then moves up to the next level.  Programmers rarely work in a language or technology vacuum.  Doing anything useful requires you know at least a few different &amp;#8220;subjects&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Still up for debate however, is whether to allow 9 programmer-year-olds to write blog posts for your firm&amp;#8230;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/DosaQ9JZMWQ" height="1" width="1"/&gt;</content>
      <author>
        <name>Jason Carpenter</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/11/02/i-am-9-programmer-years-old/</feedburner:origLink></entry>
  
    <entry>
      <title>Changing Your Stripes</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/hwkdTcDbrHI/" />
      <id>4ea99dcedabe9d44b3003daf</id>
      <updated>2011-11-01T08:31:34-04:00</updated>
      <published>2011-11-01T08:29:00-04:00</published>
      <content type="html">&lt;p&gt;Recently we made good on a long-held idea that there should be a weekend for finishing things.  Enter &lt;a href="https://www.finishweekend.com"&gt;Finish Weekend&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We knew we&amp;#8217;d need registration to tell us how many people would be coming.  Obviously this plays a part in the size of our space, the food we provide, and the number of T-Shirts.  To keep the registration honest, we decided to charge a small fee to each registrant.  That&amp;#8217;s where &lt;a href="http://stripe.com"&gt;Stripe&lt;/a&gt; comes in.&lt;/p&gt;
&lt;p&gt;Stripe uses a two part approach.  First, using their Stripe.js library, you send the credit card information to their secure servers and they send back a single use token. (We&amp;#8217;re using coffeescript here)&lt;br /&gt;
&lt;pre class="javascript"&gt;&lt;code&gt;Stripe.createToken({
  number: $('.card-number').val(),
  cvc: $('.card-cvc').val(),
  exp_month: $('.card-expiry-month').val(),
  exp_year: $('.card-expiry-year').val()
  }, amount, (status, response)-&amp;gt;
    if status == 200
      $form = $("#registration-form")
      $form.find("#stripeToken").val(respond[id])
      $form[0].submit()
    else
      if $(".alert-message").length
        $(".alert-message").remove();
      $(".page-header").after("&amp;lt;div class='alert-message error'&amp;gt;#{response.error.message}&amp;lt;/div&amp;gt;")
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;This token is then submitted with in a form to your servers where you can make use of one of Stripe&amp;#8217;s libraries to &lt;strong&gt;actually&lt;/strong&gt; charge the card.  We use Ruby on Rails, so our code looked something like this:&lt;br /&gt;
&lt;pre class="ruby"&gt;&lt;code&gt;Stripe.api_key = Rails.env.production? ? "LIVE_PRIVATE_KEY : "TEST_PRIVATE_KEY"
charge = Stripe::Charge.create(
  :amount =&amp;gt; 1000,
  :currency =&amp;gt; "usd",
  :card =&amp;gt; token,
  :description =&amp;gt; "Finish Weekend Registration (#{params[:person][:name]})"
)
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Part of the magic of the token passing process is having a public/private key set to be able to pass around.  Since these are different for the test and live environments, we do a little magic of our own.  We&amp;#8217;re using Rails 3.1 for Finish Weekend, so we can just tack on &lt;strong&gt;.erb&lt;/strong&gt; to the end of our script file which allows us to do this:&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;Stripe.setPublishableKey('&amp;lt;%= Rails.env.production? ? 'LIVE_PK' : 'TEST_PK' %&amp;gt;')
&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;
&lt;p&gt;Overall Stripe has been awesome to work with.  We got this &lt;strong&gt;up and running in less than an hour&lt;/strong&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/hwkdTcDbrHI" height="1" width="1"/&gt;</content>
      <author>
        <name>Tim Bugai</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/11/01/changing-your-stripes/</feedburner:origLink></entry>
  
    <entry>
      <title>Install Ruby 1.9.3 with libyaml on CentOS</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/mLA2C9-SUO0/" />
      <id>4eaebcf0dabe9d11bd001fa5</id>
      <updated>2011-10-31T11:26:13-04:00</updated>
      <published>2011-10-31T11:21:00-04:00</published>
      <content type="html">&lt;p&gt;Ruby 1.9.3-p0 makes psych—the replacement for 1.8.7&amp;#8217;s &lt;span class="caps"&gt;YAML&lt;/span&gt; library, Syck—the default &lt;span class="caps"&gt;YAML&lt;/span&gt; parser. Psych is a wrapper around libyaml, so you&amp;#8217;re going to need it installed and configured &lt;em&gt;before&lt;/em&gt; installing Ruby.&lt;/p&gt;
&lt;p&gt;If you install 1.9.3-p0 without libyaml, you&amp;#8217;ll see warnings like this:&lt;/p&gt;
&lt;pre class="text"&gt;It seems your ruby installation is missing psych (for YAML output).
To eliminate this warning, please install libyaml and reinstall your ruby.&lt;/pre&gt;
&lt;h2&gt;Installing libyaml&lt;/h2&gt;
&lt;pre class="shell"&gt;&lt;code&gt;$ wget http://pyyaml.org/download/libyaml/yaml-0.1.4.tar.gz
$ tar xzvf yaml-0.1.4.tar.gz
$ cd yaml-0.1.4
$ ./configure --prefix=/usr/local
$ make
$ make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Quick review of what&amp;#8217;s going on: download and untar the source code, change to the directory and install the package. You may need to sudo the &lt;code&gt;make install&lt;/code&gt; command. Your mileage may vary.&lt;/p&gt;
&lt;h2&gt;Installing Ruby 1.9.3-p0&lt;/h2&gt;
&lt;pre class="shell"&gt;&lt;code&gt;$ wget http://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p0.tar.gz
$ tar xzvf ruby-1.9.3-p0.tar.gz
$ cd ruby-1.9.3-p0
$ ./configure --prefix=/usr/local --enable-shared --disable-install-doc --with-opt-dir=/usr/local/lib
$ make
$ make install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After installing, you can verify that Ruby was installed with &lt;code&gt;ruby -v&lt;/code&gt;. It&amp;#8217;s also worth trying &lt;code&gt;gem --version&lt;/code&gt; to make sure you don&amp;#8217;t get any errors regarding psych.&lt;/p&gt;
&lt;p&gt;I tried installing &lt;code&gt;libyaml-devel&lt;/code&gt; and &lt;code&gt;libyaml&lt;/code&gt; from Yum, but couldn&amp;#8217;t get ruby installed and recognizing those packages. Out of frustration, I turned to installing libyaml by source and it Just Worked™.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/mLA2C9-SUO0" height="1" width="1"/&gt;</content>
      <author>
        <name>Brian Ryckbost</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/10/31/install-ruby-193-with-libyaml-on-centos/</feedburner:origLink></entry>
  
    <entry>
      <title>Thinking about Ruby's Symbols</title>
      <link href="http://feedproxy.google.com/~r/collectiveidea/~3/-Tm6Vf5gS8E/" />
      <id>4ea45d0edabe9d6b590194fc</id>
      <updated>2011-10-24T11:32:04-04:00</updated>
      <published>2011-10-23T21:45:00-04:00</published>
      <content type="html">&lt;p&gt;I just returned from &lt;a href="/training/"&gt;teaching&lt;/a&gt; Ruby &amp;amp; Rails in L.A. and I got thinking about Ruby&amp;#8217;s Symbols. Symbols quickly become second-nature to Rubyists, but they&amp;#8217;re difficult to teach.&lt;/p&gt;
&lt;p&gt;Those new to Ruby see something like:&lt;/p&gt;
&lt;pre class="ruby"&gt;Person.where(:name =&amp;gt; 'Daniel')&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;lt;%= form.text_field :name %&amp;gt;&lt;/pre&gt;
&lt;p&gt;and begin to get confused. Even when I start in plain Ruby and introduce symbols, usually saying &amp;#8220;they&amp;#8217;re mainly used as keys in a Hash&amp;#8221; I get strange looks. They try to figure out what a symbol &amp;#8220;means&amp;#8221; and think of it as a variable. This is understandable. I usually try to tell those hung up on the &amp;#8220;why&amp;#8221; of symbols to give them a chance and they&amp;#8217;ll soon understand how symbols are used.&lt;/p&gt;
&lt;p&gt;In a case like validations or associations, they get confused because we&amp;#8217;re using symbols instead of the actual thing: the column, model, or table.&lt;/p&gt;
&lt;pre code="ruby"&gt;validates :name, :presence =&amp;gt; true

belongs_to :company&lt;/pre&gt;
&lt;p&gt;Seasoned Rubyists know that we do that because we&amp;#8217;re not referring to the actual thing. We don&amp;#8217;t want the column value, we want an identifier to that thing that we can use later.&lt;/p&gt;
&lt;h2&gt;Hashes&lt;/h2&gt;
&lt;p&gt;Then we see things in Ruby that &lt;strong&gt;look&lt;/strong&gt; like symbols, but backwards.&lt;/p&gt;
&lt;p&gt;Console/log output:&lt;/p&gt;
&lt;pre class="ruby"&gt;
&amp;gt; Person.where(:name =&amp;gt; 'Daniel').first
=&amp;gt; #&amp;lt;Person name: "Daniel", style: "awesome"&amp;gt;&lt;/pre&gt;
&lt;p&gt;Ok, that&amp;#8217;s just some output, and it looks more like &lt;span class="caps"&gt;JSON&lt;/span&gt; than Ruby, but we&amp;#8217;ll frequently end up setting (and getting) them using a hash, making it more confusing.&lt;/p&gt;
&lt;pre class="ruby"&gt;person = Person.new(:name =&amp;gt; 'Daniel', :style=&amp;gt; 'awesome')
person[:name] = 'Dan'
&lt;/pre&gt;
&lt;p&gt;I think this waters down symbols a bit, but really you don&amp;#8217;t have to truly understand symbols to use Ruby or Rails, just know when they&amp;#8217;re used.&lt;sup class="footnote"&gt;&lt;a href="#fn1"&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2&gt;Ruby 1.9&lt;/h2&gt;
&lt;p&gt;Symbols might become even more confusing with Ruby 1.9&amp;#8217;s new Hash syntax:&lt;/p&gt;
&lt;pre class="ruby"&gt;Person.create(name: 'Daniel', style: 'awesome')
Person.where(name: 'Daniel')
&lt;/pre&gt;
&lt;p&gt;What?!? So we&amp;#8217;re defining hashes with symbol keys, and a symbol is &lt;a href="http://ruby-doc.org/core-1.9.2/Symbol.html" title="&amp;lt;code&amp;gt;:name&amp;lt;/code&amp;gt;"&gt;defined as beginning with a colon&lt;/a&gt; but we&amp;#8217;re writing it with a colon on the other side?!?&lt;/p&gt;
&lt;p&gt;Look at this and tell me it isn&amp;#8217;t confusing:&lt;/p&gt;
&lt;pre class="ruby"&gt;&amp;gt; h = {name: 'Daniel'}
=&amp;gt; {:name=&amp;gt;"Daniel"} 
&amp;gt; h[:name]
=&amp;gt; "Daniel" 
&amp;gt; h[name:]
SyntaxError: (irb):3: syntax error, unexpected ']'&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;m not sure this will make explaining symbols any easier. It sort of meshes with the console output, but even &lt;code&gt;irb&lt;/code&gt; displays using the older syntax. I&amp;#8217;m actually a fan of the new syntax&lt;sup class="footnote"&gt;&lt;a href="#fn2"&gt;2&lt;/a&gt;&lt;/sup&gt;. It looks more like JavaScript (and Python) and saves characters, but unfortunately I suspect it will create new confusion.&lt;/p&gt;
&lt;p&gt;Take this example:&lt;/p&gt;
&lt;pre class="ruby"&gt;validates :name, presence: true&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;:name&lt;/code&gt; is a pure Symbol, so the colon goes before. &lt;code&gt;presence:&lt;/code&gt; is a symbol, but used as a Hash key. Sheesh.&lt;/p&gt;
&lt;h2&gt;Final Thoughts&lt;/h2&gt;
&lt;p&gt;We definitely want to move the language forward, but we have to be careful to not confuse new users. A common source of bugs among my training students is missing colons, thereby raising unexpected exceptions.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m not sure what&amp;#8217;s needed, but maybe a rethink of how we access hashes. Would it make things easier if &lt;code&gt;h[name:]&lt;/code&gt; worked? Would it be better if all hashes acted like &lt;code&gt;HashWithIndifferentAccess&lt;/code&gt; and we could access them with &lt;code&gt;h['name']&lt;/code&gt;? I&amp;#8217;m not sure.&lt;/p&gt;
&lt;p&gt;Symbols are a fantastic Ruby concept and make the language much more expressive. When combined with good syntax highlighting, they also help differentiate code from strings. Unfortunately, they&amp;#8217;re only going to get more confusing for newbies.&lt;/p&gt;
&lt;p class="footnote" id="fn1"&gt;&lt;sup&gt;1&lt;/sup&gt; I&amp;#8217;m a believer that mastery comes with time. For example, I didn&amp;#8217;t truly understand how &lt;code&gt;.each {}&lt;/code&gt; worked while I was getting started with Ruby, but it didn&amp;#8217;t hold me back from using it. You need to recognize and be able to use the syntax, not know how passing blocks works behind the scenes.&lt;/p&gt;
&lt;p class="footnote" id="fn2"&gt;&lt;sup&gt;2&lt;/sup&gt; I wish it would have been done this way originally. The community isn&amp;#8217;t bold enough to rip out the old way completely in 2.0. Maybe 3.0?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/collectiveidea/~4/-Tm6Vf5gS8E" height="1" width="1"/&gt;</content>
      <author>
        <name>Daniel Morrison</name>
      </author>
    <feedburner:origLink>http://collectiveidea.com/blog/archives/2011/10/23/thinking-about-rubys-symbols/</feedburner:origLink></entry>
  
</feed>

