<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Alex Kahn Blog</title>
 <link href="http://akahn.net/atom.xml" rel="self" />
 <link href="http://akahn.net/"/>
 <updated>2011-10-12T12:03:44-04:00</updated>
 <id>http://akahn.net</id>
 <author>
   <name>Alex Kahn</name>
   <email>alexanderkahn@gmail.com</email>
 </author>

 
 <entry>
   <title>Working Through Git Conflicts in Vim</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2011/10/12/working-through-git-conflicts-in-vim.html" />
   <updated>2011-10-12T00:00:00-04:00</updated>
   <id>http://akahn.net/2011/10/12/working-through-git-conflicts-in-vim</id>
   <content type="html">&lt;p&gt;In this post I present a workflow I use to help me efficiently go through Git merge conflicts and correct them. It eliminates some of the typing and tedium involved in this process.&lt;/p&gt;

&lt;p&gt;It starts with a shell alias, &lt;code&gt;conflicts&lt;/code&gt;. The alias is defined as:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;span class='nb'&gt;alias &lt;/span&gt;&lt;span class='nv'&gt;conflicts&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;git ls-files --unmerged | cut -f2 | uniq&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In Git, &lt;code&gt;unmerged&lt;/code&gt; means a file that couldn&amp;#8217;t be merged because of a conflict. So this Git command lists all of the objects containing conflicts. I pipe that command&amp;#8217;s output to &lt;code&gt;cut -f2&lt;/code&gt; to get the second column of its output, the filenames. I then remove repeat entries using &lt;code&gt;uniq&lt;/code&gt;, since this &lt;code&gt;ls-files&lt;/code&gt; command outputs multiple objects for each conflict.&lt;/p&gt;

&lt;p&gt;When I want to start resolving conflicts, I issue the command &lt;code&gt;conflicts | xargs mvim&lt;/code&gt;. &lt;code&gt;xargs&lt;/code&gt; is a powerful tool that takes its standard input – in this case, a list of files – and and provides that to a command as arguments. So, MacVim receives the list of conflicting files as arguments and loads the files into its buffer list.&lt;/p&gt;

&lt;p&gt;I then fix the first conflict. If I&amp;#8217;m dealing with a particularly long file, I use &lt;code&gt;/&lt;/code&gt; to search for &lt;code&gt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&lt;/code&gt; or other such conflict markers that Git places in the file.&lt;/p&gt;

&lt;p&gt;When I&amp;#8217;m done fixing the conflict, I execute &lt;code&gt;:Git add %&lt;/code&gt; to add the file to the Git index. &lt;a href='https://github.com/tpope/vim-fugitive'&gt;fugitive.vim&lt;/a&gt;, Time Pope&amp;#8217;s essential Git intergation tool for Vim, provides the &lt;code&gt;:Git&lt;/code&gt; command which passes through your command to the &lt;code&gt;git&lt;/code&gt; command line. On the Vim command line &lt;code&gt;%&lt;/code&gt; refers to the current file.&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Having fixed a conflict and added a file to the Git index, I&amp;#8217;m ready to deal with the next conflict. To get to the next conflicted file I use &lt;code&gt;:bdelete&lt;/code&gt;, or &lt;code&gt;:bd&lt;/code&gt; for short. Since we started Vim with a series of files as command line arguments, the buffer list is loaded with all the files we need to edit. &lt;code&gt;:bdelete&lt;/code&gt; discards the current one and loads the next one. I repeat this process until there are no buffers left.&lt;/p&gt;

&lt;p&gt;Once there are no remaining conflicts, I close my Vim window, go back to a terminal, and complete the merge using &lt;code&gt;gc&lt;/code&gt;. What is &lt;code&gt;gc&lt;/code&gt;? It&amp;#8217;s an alias for &lt;code&gt;git commit --verbose&lt;/code&gt;. Verbose commit output is awesome because it shows exactly what you&amp;#8217;re about to commit. It saves me the step of doing &lt;code&gt;git diff&lt;/code&gt; before each commit. I never want to commit without &lt;code&gt;--verbose&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And that&amp;#8217;s it. If this tended to be a long process or one I undertook more often, I could automate it further by creating a Vim command that combines the &lt;code&gt;git add&lt;/code&gt; and &lt;code&gt;:bdelete&lt;/code&gt; steps. As it stands, this workflow eliminates typing out long filenames and introduces a pleasant rhythm to this process. I hope this post has inspired you to script the tedious workflows in your Unix life. What tedious operations would you like to automate away?&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;&lt;code&gt;%&lt;/code&gt; is a great feature that I recommend &lt;a href='http://vimdoc.sourceforge.net/htmldoc/cmdline.html#cmdline-special'&gt;reading up on&lt;/a&gt;. Also check out the bash-like &lt;a href='http://vimdoc.sourceforge.net/htmldoc/cmdline.html#filename-modifiers'&gt;filename modifiers&lt;/a&gt; that you can use with &lt;code&gt;%&lt;/code&gt;. Most often, I use the &amp;#8220;head&amp;#8221; modifier, &lt;code&gt;:h&lt;/code&gt;, to change to the directory of the current file: &lt;code&gt;:cd %:h&lt;/code&gt;. Or, if I&amp;#8217;m editing a new file in a directory that doesn&amp;#8217;t exist yet, I can create the directory: &lt;code&gt;:!mkdir -p %:h&lt;/code&gt;.&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>ConnectionAttempt: Another Rails Refactoring</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2011/10/03/connection-attempt-another-rails-refactoring.html" />
   <updated>2011-10-03T00:00:00-04:00</updated>
   <id>http://akahn.net/2011/10/03/connection-attempt-another-rails-refactoring</id>
   <content type="html">&lt;p&gt;In the last few months I&amp;#8217;ve been learning a lot about object-oriented design. By following the conversations and writings of Avdi Grimm, Corey Haines, Steve Klabnik, Gary Bernhardt and others (even going way back to &lt;a href='http://jamesgolick.com/2010/3/14/crazy-heretical-and-awesome-the-way-i-write-rails-apps.html'&gt;James Golick&lt;/a&gt;), I&amp;#8217;ve been able to identify some design issues in the codebase I work on every day at Paperless Post. These are issues that I had sensed previously, but had lacked a vocabulary with which to discuss them. In this post I consider a refactoring I undertook recently in our codebase. Through this discussion, I hope to help spread the good word on design in Rails applications.&lt;/p&gt;

&lt;p&gt;The code I&amp;#8217;m working with here is for Paperless Post&amp;#8217;s integration with Eventbrite. Recently, we launched a feature that allows users to connect their account with an Eventbrite account. This allows users to link invitations on our site with ticketed events on Eventbrite. As a new requirement emerged, my original implementation became inadequate.&lt;/p&gt;

&lt;h3 id='the_old_code'&gt;The Old Code&lt;/h3&gt;

&lt;p&gt;The following controller is responsible for connecting a user&amp;#8217;s account with their account on Eventbrite:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;EventbriteAccountConnectionsController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;create&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;connection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;EventbriteAccountConnection&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
        &lt;span class='ss'&gt;:account_id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;current_account&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='ss'&gt;:email&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:email&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='ss'&gt;:password&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:password&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
      &lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;client_messenger&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;add_notice&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Successfully logged in to Eventbrite.&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;client_messenger&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:connection_id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;connection&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='n'&gt;client_messenger&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;add_error&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Sorry, we were unable to log you in to Eventbrite.&amp;quot;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='n'&gt;send_messages&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;There are two details to note here. One is that &lt;code&gt;client_messenger&lt;/code&gt; and &lt;code&gt;send_messages&lt;/code&gt; are methods that deal with a &lt;code&gt;ClientMessenger&lt;/code&gt;, an object for preparing and sending JSON responses to the client. I&amp;#8217;ll use this again later on. The other detail is that when connecting accounts is successful, the client needs the ID of the connection record, so the controller must include this data in the response.&lt;/p&gt;

&lt;p&gt;This is the model code that is called by the controller:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;EventbriteAccountConnection&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nc'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nf'&gt;connect&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;credentials&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;resp&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;EventbriteClient&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;user_get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;credentials&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:email&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;credentials&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:password&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;return&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;error&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;create&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
      &lt;span class='ss'&gt;:account_id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;credentials&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:account_id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='ss'&gt;:code&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;user&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;user_key&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt;
      &lt;span class='ss'&gt;:remote_id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;resp&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;user&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;][&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;user_id&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This code attempts to fetch a user from Eventbrite&amp;#8217;s API and, if successful, creates and returns a connection record. If the API request responds with an error, the method returns &lt;code&gt;nil&lt;/code&gt;. This code worked reliably, but eventually our team wanted to convey error messages from Eventbrite to users rather than just indicating success or failure. This way we would be able to distinguish between a failure with the user&amp;#8217;s Eventbrite account, or a mistake on our site.&lt;/p&gt;

&lt;p&gt;The most immediate solution to this problem would have been to modify the model method to return a more descriptive response in the case of failure. Then the controller could receive the error message and pass it along to users. This means that in case of success, the method would return an &lt;code&gt;EventbriteAccountConnection&lt;/code&gt; whereas in failure it would return a &lt;code&gt;String&lt;/code&gt;. Maybe it&amp;#8217;s the Haskell talking, but I tend to think of wildly differing return types as a code smell. If the types respond to the same messages, it&amp;#8217;s all good: duck-typing should be embraced in our code. But in this case there would be little recourse other than to check the type of the response: if the controller gets back a &lt;code&gt;String&lt;/code&gt;, there was an error; if it gets an &lt;code&gt;EventbriteAccountConnection&lt;/code&gt;, success. Ick.&lt;/p&gt;

&lt;p&gt;A better option would be to for &lt;code&gt;EventbriteAccountConnection.connect&lt;/code&gt; to return a &lt;code&gt;Struct&lt;/code&gt; subclass that has a slot for an error message and a slot for an &lt;code&gt;EventbriteAccountConnection&lt;/code&gt; instance. If the connection instance is present, that indicates success. If it&amp;#8217;s missing, the login failed, and we should display the struct&amp;#8217;s error attribute.&lt;/p&gt;

&lt;p&gt;This could be a workable solution, but it sidesteps some fundamental design problems in &lt;code&gt;EventbriteAccountConnection.connect&lt;/code&gt;. The most obvious issue to me was that it is a class method. I don&amp;#8217;t think, &lt;a href='http://andrzejonsoftware.blogspot.com/2011/07/yes-nick-class-methods-are-evil.html'&gt;as some do&lt;/a&gt;, that class methods are evil. However, they can indicate an attempt to use a class as a &amp;#8220;bucket of methods,&amp;#8221; ignoring or avoiding the advantages of encapsulating data and behavior in an object. In this case, I defined this as a class method because I could sense that the ActiveRecord model couldn&amp;#8217;t provide the encapsulation I needed. But at the time, I didn&amp;#8217;t take the further step of defining a &lt;em&gt;new&lt;/em&gt; class to abstract out the connection logic.&lt;/p&gt;

&lt;h3 id='the_new_code'&gt;The New Code&lt;/h3&gt;

&lt;p&gt;Given the additional requirement of improved error propagation, I took the opportunity to extract this account connection logic into a new domain object. Here is the code I arrived at, with some details omitted:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;EventbriteAccountConnection&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ConnectionAttempt&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;account&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;email_address&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;password&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@account&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;account&lt;/span&gt;
    &lt;span class='vi'&gt;@response&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;EventbriteClient&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;user_get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;email_address&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;password&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vi'&gt;@connection&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;save_connection&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;as_messenger&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;messenger&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;ClientMessenger&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;success?&lt;/span&gt;
      &lt;span class='n'&gt;messenger&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Successfully logged in to Eventbrite.&amp;quot;&lt;/span&gt;
      &lt;span class='n'&gt;messenger&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:connection_id&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@connection&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;
    &lt;span class='k'&gt;else&lt;/span&gt;
      &lt;span class='n'&gt;messenger&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;add_error&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;error_message&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='n'&gt;messenger&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This my not be the greatest Ruby class ever, but it&amp;#8217;s a significant improvement in design. To use the terminology of Hal Abelson and Gerald Sussman in &lt;em&gt;Structure and Interpretation of Computer Programs&lt;/em&gt;, I have created a data abstraction, binding together an account and some login information into a bundle that has some meaning. By introducing the name &lt;code&gt;ConnectionAttempt&lt;/code&gt; I have brought to the surface – I have reified – a concept that was previously submerged. This will aid future readers and maintainers of this code. After all, the goal of code is not just to provide instructions for the computer to carry out – it is also to communicate meaning to other humans. In this sense, this refactoring is a success.&lt;/p&gt;

&lt;p&gt;The new service object also yields a simpler controller:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;EventbriteAccountConnectionsController&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ApplicationController&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;create&lt;/span&gt;
    &lt;span class='n'&gt;render&lt;/span&gt; &lt;span class='ss'&gt;:json&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;EventbriteAccountConnection&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ConnectionAttempt&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;
      &lt;span class='n'&gt;current_account&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:email&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;params&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:password&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;as_messenger&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is my ideal controller: it contains no logic. It merely calls out to a collaborator, passing it some parameters, and returns a response. While, in many cases, building a response directly in the controller is appropriate, in this case, given the non-trivial logic for generating the response, I&amp;#8217;ve made this the responsibility of &lt;code&gt;ConnectionAttempt&lt;/code&gt;. This prevents the controller from having to reach into its collaborator to query its internal state. It tells the object what it wants rather than asking.&lt;/p&gt;

&lt;p&gt;The entirety of the ActiveRecord model is now:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;EventbriteAccountConnection&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This svelte class now respects the Single Responsibility Principle. Its sole purpose is to persist account connections to the database.&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;ConnectionAttempt&lt;/code&gt; has a narrow interface to &lt;code&gt;EventbriteAccountConnection&lt;/code&gt;, it&amp;#8217;s easy to mock out this external dependency. This makes the tests faster since it eliminates the need to persist ActiveRecord objects to the database. It also allows running the test without loading the entire Rails application. But there&amp;#8217;s an additional, more subtle advantage to this use of mocking. By isolating &lt;code&gt;ConnectionAttempt&lt;/code&gt; from the &lt;code&gt;EventbriteAccountConnection&lt;/code&gt; that it ultimately attempts to create, the test becomes clearer because it takes advantage the abstraction barrier between the two domain concepts, allowing the test to focus more strictly on the object under test.&lt;/p&gt;

&lt;h3 id='discussion'&gt;Discussion&lt;/h3&gt;

&lt;p&gt;It&amp;#8217;s a bit silly how revelatory this feels to me. Object-oriented design has never been kept a secret, yet it seems this knowledge has been forgotten in the context of Rails applications. At the same time, to some to some, this design knowledge has been a given for years. In my case, although I read James Golick&amp;#8217;s post on the topic almost two years ago, when I was starting to use Ruby and Rails, I didn&amp;#8217;t piece it all together until recently. Now I know that by paying attention to design, we can build more maintainable, more understandable Rails apps, with faster test suites.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;d like to hear from you. What do you think of this code? How would you continue this refactoring? What design strategies have you applied in your Rails apps, and what lessons have you learned?&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>My Haskell Reading List</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2011/04/18/my-haskell-reading-list.html" />
   <updated>2011-04-18T00:00:00-04:00</updated>
   <id>http://akahn.net/2011/04/18/my-haskell-reading-list</id>
   <content type="html">&lt;p&gt;Lately I&amp;#8217;ve been spending some time experimenting with Haskell, attempting to learn the fundamentals of functional programming. This post is meant to share some of the interesting resources I&amp;#8217;ve come across in exploring this new world. How did I, a humble Rubyist, get mixed up with Haskell? There were a couple forces pushing me in the functional direction. One was &lt;a href='http://twitter.com/ultror'&gt;Jonas Westerlund&lt;/a&gt;. Jonas is a Swedish hacker who works in Python and JavaScript by day and Haskell by night. I eventually became attracted to the folds, lazy evaluation, and infinite lists he showed off continually in IRC. Reading the source for his IRC bot, &lt;a href='https://github.com/nlogax/norby'&gt;norby&lt;/a&gt;, especially its &lt;a href='https://github.com/nlogax/norby/blob/master/src/Parser.hs'&gt;IRC parser&lt;/a&gt; and the main bot module – which responds to commands in separate threads using &lt;a href='https://github.com/nlogax/norby/blob/master/src/Bot.hs#L57'&gt;one little &lt;code&gt;forkIO&lt;/code&gt; call&lt;/a&gt; – has been a gentle way to get acquainted with some real world Haskell code.&lt;/p&gt;

&lt;p&gt;I was also exposed to functional programming ideas recently when I read Gregory Brown&amp;#8217;s &lt;em&gt;Ruby Best Practices&lt;/em&gt;. This is a fantastic book and definitely helped me level up in Ruby. Relevant here is that this book dedicates &lt;a href='http://majesticseacreature.com/rbp-book/pdfs/ch05.pdf'&gt;a whole chapter&lt;/a&gt; to discussing functional programming techniques in Ruby. The author concludes that while Ruby is by no means a functional language, its functional influences have yielded some very powerful abilities. The chapter goes through several examples of idiomatic Ruby that take functional approaches to problem-solving. Some examples are lazy evaluation (with a discussion of MenTaLguY&amp;#8217;s &lt;a href='http://moonbase.rydia.net/software/lazy.rb/'&gt;lazy.rb&lt;/a&gt;), memoization, &lt;code&gt;Enumerable#inject&lt;/code&gt; (and why folds are not very efficient in Ruby), infinite lists, and some snazzy &lt;code&gt;Symbol#to_proc&lt;/code&gt; magic. This chapter is a testament to the elegance of functional approaches to solving problems and to the power Ruby unlocks by tapping into some of Smalltalk&amp;#8217;s functional features. Flip through it and you might find a new appreciation for some of Ruby&amp;#8217;s design decisions.&lt;/p&gt;

&lt;p&gt;Another reason for my exploration of functional programming is &lt;a href='http://nodejs.org/'&gt;Node.js&lt;/a&gt;. The explosive popularity of Node and the resulting backlash by concurrency curmudgeons has been interesting to follow but has not always been illuminating. The &amp;#8220;events versus threads&amp;#8221; debate has been going on for something like twenty years: which side is right? It turns out that, after brushing aside the trolls, flamebait and hype, this isn&amp;#8217;t the right question to ask. Threads and evented programming are both tools that can be used to write concurrent programs; which technology is correct depends on the problem at hand. This is illustrated most clearly in a paper that Coda Hale pointed me to. In &lt;a href='http://repository.upenn.edu/cgi/viewcontent.cgi?article=1391&amp;amp;context=cis_papers' title='Combining Events And Threads For Scalable Network Services: Implementation And Evaluation Of Monadic, Application-level Concurrency Primitives by Peng Li and Stephan Zdancewic'&gt;Combining Events And Threads For Scalable Network Services&lt;/a&gt;, published in 2007, Peng Li and Stephan Zdancewic describe building a network service that takes a hybrid approach by using threads &lt;em&gt;and&lt;/em&gt; events. In the end, these don&amp;#8217;t have to be competing techniques; they can compliment each other. Equally important, this paper demonstrates that callbacks are not a necessary byproduct of event-driven code. Indeed, the system the paper describes abstracts away the callback spaghetti that can often make up Node programs.&lt;/p&gt;

&lt;p&gt;Much of the rest of my reading has been around concurrency. Continuing on the subject of non-blocking IO, Gregory Collins&amp;#8217; talk at the recent QCon London, &lt;a href='http://qconlondon.com/dl/qcon-london-2011/slides/GregoryCollins_HighPerformanceWebApplicationsInHaskell.pdf'&gt;High Performance Web Applications in Haskell&lt;/a&gt; (warning: 18 MB PDF), discussed Haskell&amp;#8217;s threading model at length. From his slides, we learn that Haskell uses lightweight threads that are mapped N:M to OS threads. These threads are scheduled by the runtime system and have very low overhead in terms of memory use and context switching. All system calls in Haskell are non-blocking. This system yields performance similar to that of evented frameworks, but steers clear of the need for deeply nested callbacks.&lt;/p&gt;

&lt;p&gt;Haskell has no problem dealing with tens of thousands threads, but what about synchronization? One option is software transactional memory (STM). STM allows the programmer to treat shared resources as they would a database transaction, rolling back changes if another thread has modified a resource. I first encountered this construct in David Nolen&amp;#8217;s blog posts on &lt;a href='http://dosync.posterous.com/stm-couchdb-and-pushing-5500-documentssecond'&gt;using STM for bulk inserts with CouchDB&lt;/a&gt; and &lt;a href='http://dosync.posterous.com/clojure-nodejs-and-why-messaging-can-be-lame'&gt;comparing concurrency in Clojure and Node.js&lt;/a&gt;. More recently I came across &lt;a href='http://repository.upenn.edu/cgi/viewcontent.cgi?article=1391&amp;amp;context=cis_papers'&gt;a 2006 interview with Simon Peyton-Jones and Tim Harris&lt;/a&gt; laying out their research and approach to implementing STM in Haskell. Other languages have follewed suit in implementing STM.&lt;/p&gt;

&lt;p&gt;However, STM is not a silver bullet. Users of the feature have found that its performance can be unpredictable. In this &lt;a href='http://www.azulsystems.com/blog/cliff/2008-05-27-clojure-stms-vs-locks'&gt;discussion between Rich Hickey (creator of Clojure) and Cliff Click&lt;/a&gt;, Click describes a problem where a program written using STM becomes dependent on the runtime system and the hardware it&amp;#8217;s run on. Changing the hardware or using a version of Clojure with updated STM internals resulted vastly different performance, sometimes requiring a rewrite of the program. This discussion, from 2008, illustrates some of the pitfalls of STM, and how it should be used appropriately. I&amp;#8217;m curious to find out if and how these issues have been addressed in the years since this discussion.&lt;sup id='fnref:1'&gt;&lt;a href='#fn:1' rel='footnote'&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;This covers some ground on the subject of concurrency on a single machine. But what about using Haskell for writing distributed programs? In &lt;a href='http://research.microsoft.com/en-us/um/people/simonpj/papers/parallel/remote.pdf'&gt;Haskell for the cloud&lt;/a&gt;, a wonderfully clear and well-written paper, Jeff Epstein, Andrew P. Black, and Simon Peyton-Jones describe implementing a distributed system that emulates the message passing functionality of Erlang, with some added Haskell flair. An interesting diversion from Erlang is the implementation of typed channels, reminiscent of Go (thanks to Ilya Grigorik for his &lt;a href='http://www.igvita.com/2010/12/02/concurrency-with-actors-goroutines-ruby/'&gt;explanation of typed channels in Go&lt;/a&gt;, which better suit Haskell&amp;#8217;s strong typing than the Erlang message passing model, where a message of any type can be dispatched to any process. The code for this system, known as Cloud Haskell, is &lt;a href='https://github.com/jepst/CloudHaskell'&gt;available on GitHub&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another great discussion of Erlang, Haskell, and concurrency is a talk given by Simon Peyton-Jones, one of the creators of Haskell, at Erlang Factory London 2009 entitled &lt;a href='http://www.erlang-factory.com/conference/London2009/speakers/SimonPeytonJones'&gt;Haskell and Erlang: growing up together&lt;/a&gt;. This entertaining presentation provides a brief overview of the history of each language, describes the features that distinguish them, and argues that despite their differences, both languages (and functional programming generally) are very relevant for solving today&amp;#8217;s engineering problems. The talk provides a great survey of concurrency in Haskell, including a brief mention of data parellelism, an approach I still need to read more on. Be sure to follow along with the &lt;a href='http://www.erlang-factory.com/upload/presentations/116/SimonPeyton-Jones-ErlangFactoryLondon2009-HaskellandErlangGrowinguptogether.pdf'&gt;slightly cheesy but information-rich slides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are many more articles and resources that I have found interesting in my functional journey, but I&amp;#8217;m out of space. I want to close with a shoutout to Miran Lipovača for writing &lt;a href='http://learnyouahaskell.com/'&gt;&lt;em&gt;Learn You a Haskell for Great Good&lt;/em&gt;&lt;/a&gt;, a phenomenal book. Don&amp;#8217;t be fooled by the illustrations – this is a more straightforward book than &lt;em&gt;Why&amp;#8217;s (Poignant) Guide to Ruby&lt;/em&gt;. It&amp;#8217;s a gentle introduction to functional programming and it presents some fairly mind-bending ideas in a way that somehow manages to be accessible. For example, the book presents monads only after walking readers through functors, applicative functors and monoids. By the time you reach monads, you are fully comfortable with the idea of a value wrapped in a context. The book recognizes that programming in a purely functional language requires new ways of thinking for someone with an imperative, object-oriented background and teaches in a way that is comfortable for users of traditional languages while still remaining true to Haskell. If you&amp;#8217;re interested in buying the book, I have a one-time-use 30% off coupon code for No Starch press. Let me know you&amp;#8217;re interested and I&amp;#8217;ll share the code with you.&lt;/p&gt;
&lt;div class='footnotes'&gt;&lt;hr /&gt;&lt;ol&gt;&lt;li id='fn:1'&gt;
&lt;p&gt;For additional reading on STM, check out Hans-J. Boehm&amp;#8217;s &lt;a href='http://www.usenix.org/event/hotpar09/tech/full_papers/boehm/boehm_html'&gt;Transactional Memory Should Be an Implementation Technique, Not a Programming Interface&lt;/a&gt; and &lt;a href='http://moonbase.rydia.net/mental/blog/programming/ruby-stm-round-the-third'&gt;MenTaLguY&amp;#8217;s implementation of STM in Ruby&lt;/a&gt; (and thanks to MenTaLguY for referring me to all of the STM links in this post).&lt;/p&gt;
&lt;a href='#fnref:1' rev='footnote'&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;</content>
 </entry>
 
 <entry>
   <title>Tracking Events With Google Analytics</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2010/11/12/tracking-events-with-google-analytics.html" />
   <updated>2010-11-12T00:00:00-05:00</updated>
   <id>http://akahn.net/2010/11/12/tracking-events-with-google-analytics</id>
   <content type="html">&lt;p&gt;Did you know you can track custom events with Google Analytics? It&amp;#8217;s true; you can. It&amp;#8217;s easy. Just take your Google Analytics asynchronous queue object, &lt;code&gt;_gaq&lt;/code&gt;, and push an array onto it:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;_gaq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;_trackEvent&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;accounts&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;signup&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;homepage&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;code&gt;_trackEvent&lt;/code&gt; is the method, &lt;code&gt;accounts&lt;/code&gt; is the category, &lt;code&gt;signup&lt;/code&gt; is the action, and &lt;code&gt;homepage&lt;/code&gt; is the label. There is an additional parameter we can provide, &lt;code&gt;value&lt;/code&gt;, if our event has a numerical value that we&amp;#8217;d like to view in aggregate later on.&lt;/p&gt;

&lt;p&gt;Typically, you&amp;#8217;d set this up to happen upon a certain user action. For example, using jQuery:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;#signup-form&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;submit&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='nx'&gt;_gaq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;_trackEvent&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;accounts&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;signup&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;homepage&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When a user submits the signup form, we track the event in Google Analytics.&lt;/p&gt;

&lt;p&gt;If you need to handle many events, a more robust solution would be to describe these events in markup rather than JavaScript. In this example, for tracking clicks that download files, I place a data-attribute on links whose clicks you&amp;#8217;d like to track:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='c1'&gt;// Given HTML like this:&lt;/span&gt;
&lt;span class='c1'&gt;// &amp;lt;a href=&amp;quot;/download.pdf&amp;quot; data-track&amp;gt;Download as PDF&amp;lt;/a&amp;gt;&lt;/span&gt;

&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;a [data-track&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]).&lt;/span&gt;&lt;span class='nx'&gt;click&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;event&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='kd'&gt;var&lt;/span&gt; &lt;span class='nx'&gt;label&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;innerHTML&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nx'&gt;file&lt;/span&gt;  &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;pathname&lt;/span&gt;&lt;span class='p'&gt;;&lt;/span&gt;
  &lt;span class='nx'&gt;_gaq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;_trackEvent&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;downloads&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;file&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;label&lt;/span&gt;&lt;span class='p'&gt;);&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now our data about this download is read from the markup, rather than specified up-front in our JavaScript.&lt;/p&gt;

&lt;h3 id='tracking_pageviews'&gt;Tracking Pageviews&lt;/h3&gt;

&lt;p&gt;The stock Google Analytics snippet contains a call to &lt;code&gt;_trackPageview&lt;/code&gt;. On typical web pages we call this function once, for each page the user loads in their browser. On fancy single-page apps that navigate based on the URL hash, we may want to track each hash-based navigation as a pageview. In a Sammy app, for example, we could do this using the &lt;code&gt;after&lt;/code&gt; hook:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='js'&gt;&lt;span class='nx'&gt;$&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;sammy&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
  &lt;span class='c1'&gt;// Set up some routes&lt;/span&gt;

  &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;after&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='kd'&gt;function&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt;
    &lt;span class='nx'&gt;_gaq&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;push&lt;/span&gt;&lt;span class='p'&gt;([&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;_trackPageview&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]);&lt;/span&gt;
  &lt;span class='p'&gt;});&lt;/span&gt;
&lt;span class='p'&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now we&amp;#8217;re tracking navigation within the single-page app: our after function is called each time the user navigates to another route in the Sammy app. Simple!&lt;/p&gt;

&lt;h3 id='wrapping_up'&gt;Wrapping Up&lt;/h3&gt;

&lt;p&gt;For more detail, check out &lt;a href='http://code.google.com/apis/analytics/docs/tracking/eventTrackerGuide.html'&gt;Google&amp;#8217;s trackEvent reference&lt;/a&gt;. Also, be sure to read Mathias Bynens&amp;#8217; &lt;a href='http://mathiasbynens.be/notes/async-analytics-snippet'&gt;excellent post&lt;/a&gt; on optimizing Google&amp;#8217;s stock analytics snippet. Mathias also does an excellent job demystifying the the &lt;code&gt;_gaq&lt;/code&gt; object. One last thing: check out &lt;a href='http://code.google.com/apis/analytics/docs/tracking/gaTrackingCustomVariables.html'&gt;custom variables&lt;/a&gt;. This feature is an excellent way to keep track of different categories of visitors. At Paperless Post, we use custom variables to help us understand the behavior of anonymous visitors versus logged in users.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Gotham Ruby Conference 2010: A Recap</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2010/05/26/gotham-ruby-conference.html" />
   <updated>2010-05-26T00:00:00-04:00</updated>
   <id>http://akahn.net/2010/05/26/gotham-ruby-conference</id>
   <content type="html">&lt;p&gt;Over the weekend I attended the fourth &lt;a href=&quot;http://www.goruco.com/&quot;&gt;Gotham Ruby Conference&lt;/a&gt; (GoRuCo). The conference was well-organized, the content was top-notch and there were tons of great people there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;http://farm4.static.flickr.com/3306/4629071041_8b0b0c7c36.jpg&quot; alt=&quot;&quot; /&gt;&lt;br /&gt;
&lt;a href=&quot;http://www.flickr.com/photos/sd/&quot;&gt;Photo by sd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The day opened with a welcome from a Pace University&amp;#8217;s Jonathan Hill. Jonathan, who is assistant dean of Pace&amp;#8217;s Computer Science program, described the longstanding relationship between Pace and the New York Ruby community, pointing out that GoRuCo has been held at Pace since its first year. Pace uses Ruby and Rails extensively in its Computer Science program and, in turn, its graduates often find employment through this community. Jonathan expressed real appreciation for the health and energy of the Ruby community in New York. It was neat to feel this connection and know that Pace was more than just a rented space for the conference.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nick Gauthier&lt;/strong&gt; presented the first talk, Grease Your Suite, on making slow test suites run faster. This talk demonstrated how he improved a test suite in a Rails project from 13 minutes down to under 20 seconds. To do this, Nick used lifo&amp;#8217;s &lt;a href=&quot;http://github.com/lifo/fast_context&quot;&gt;fast_context&lt;/a&gt;, his own &lt;a href=&quot;http://github.com/ngauthier/hydra&quot;&gt;Hydra&lt;/a&gt; for distributing tests across &lt;span class=&quot;caps&quot;&gt;CPU&lt;/span&gt; cores or machines, and Ruby Enterprise Edition for its ability to tune Ruby&amp;#8217;s garbage collection. He also gained speed by mocking PaperClip&amp;#8217;s image manipulation, using fixtures to replace truly-resized images. Nick got further performance by tweaking a journaling setting for the &lt;code&gt;ext4&lt;/code&gt; filesystem (Nick is a staunch Linux-on-the-desktop user), as well as by disabling &lt;code&gt;atime&lt;/code&gt;. Nick noted that the improvements from these tweaks gain as much in speed as running tests on a solid state drive. With such a fast test suite, the Continuous Integration server can return to its true calling&amp;#8212;ensuring a green build in a production-like environment. While I don&amp;#8217;t have any projects that are burdened by tests that take too long, I nonetheless left this talk with strategies to grease my suite. Get all the details in &lt;a href=&quot;http://grease-your-suite.heroku.com/&quot;&gt;Nick&amp;#8217;s slides&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The next talk, by &lt;strong&gt;Aman Gupta&lt;/strong&gt;, was on a new Ruby profiling tool, Memprof. Aman provided a tour of the tools he&amp;#8217;d worked with for profiling Ruby&amp;#8217;s memory use: &lt;code&gt;ObjectSpace.each_object&lt;/code&gt;, gdb.rb, bleak_house, and patching Ruby in order for it to provide heap dumps. These tools are all helpful, he said, but they require writing patching or running special versions of Ruby, or don&amp;#8217;t provide complete enough information on the contents of the objects in memory or their context in code. Memprof, created by Joe Damato with contributions from Aman, solves the above problems: Installing it is simple (&lt;code&gt;gem install memprof&lt;/code&gt;), use is simple (&lt;code&gt;Memprof.dump_all&lt;/code&gt;, for example), it outputs to &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt;, and provides all the necessary information and context about objects in memory, including references between objects. Memprof&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;JSON&lt;/span&gt; output makes it easy to dump its output into a database like MongoDB, which &lt;a href=&quot;http://memprof.com/&quot;&gt;memprof.com&lt;/a&gt; does. Aman&amp;#8217;s talk struck at just the right level: deep enough to keep us interested, but not so deep as to lose the audience. And if you&amp;#8217;ve ever checked out &lt;a href=&quot;http://timetobleed.com/&quot;&gt;Aman and Joe&amp;#8217;s blog&lt;/a&gt; you&amp;#8217;ll know how deep this this rabbit hole goes. My thanks to Aman for that.&lt;/p&gt;
&lt;p&gt;Managing Rubyists, a talk by &lt;strong&gt;Luke Melia&lt;/strong&gt;, was directed at Ruby developers who manage a team. This was the only non-technical talk of the day and it was one of the highlights for me. In the talk, Luke laid out 15 principles or techniques for managers to follow for their team and its members to achieve happiness, motivation, productivity and growth. I was blown away by the care Luke took with this subject and the regard he has for the developers he works with. Luke takes his craft as a manager as seriously as Rubyists take their code. Check out &lt;a href=&quot;http://www.slideshare.net/lukemelia/managing-rubyists-goruco-2010-pdf&quot;&gt;Luke&amp;#8217;s slides and notes&lt;/a&gt; for the details. If you&amp;#8217;re a manager, be sure to check out Luke&amp;#8217;s &lt;a href=&quot;http://www.goodreads.com/review/list/1047137-luke?shelf=goruco-reading-list&quot;&gt;recommended reading&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;After lunch, &lt;strong&gt;Chris Williams&lt;/strong&gt; (of JSConf fame) presented Rails Caching à la JavaScript. In his talk, Chris made the case a straightforward approach to working around performance issues with Rails: using page caching to avoid the Rails stack altogether for most requests, and making &lt;span class=&quot;caps&quot;&gt;JSONP&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; requests to retrieve the personalized aspects of a page. Even though this &lt;span class=&quot;caps&quot;&gt;AJAX&lt;/span&gt; request is handled by Rails, its rendering overhead is offloaded to the client (Chris recommends &lt;a href=&quot;http://github.com/janl/mustache.js&quot;&gt;mustache.js&lt;/a&gt; for client-side rendering). Despite Chris&amp;#8217; preface that the technique described is not ideal for most Rails applications, the talk drew skepticism and ire from the audience. Nonetheless, the talk was enjoyable, humorous, and made a strong argument for a straightforward caching strategy.&lt;/p&gt;
&lt;p&gt;Next, &lt;strong&gt;Alex MacCaw&lt;/strong&gt; showcased Bowline (pronounced &amp;#8220;bowlin&amp;#8217;&amp;#8221; like &lt;a href=&quot;http://en.wikipedia.org/wiki/Bowline&quot;&gt;the knot&lt;/a&gt;), a new framework for creating cross platform desktop apps using Ruby, JavaScript and WebKit. Alex gave a tour of developing an app with Bowline, showing off its in-memory model layer, &lt;a href=&quot;http://github.com/maccman/supermodel&quot;&gt;SuperModel&lt;/a&gt;, its bindings between Ruby and JavaScript and neat features such as seamless background updates for installed applications and synchronizing data across remote client apps. In all, Bowline looks to be a very ambitious and promising project.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Paul Dix&lt;/strong&gt;, author of the forthcoming &lt;a href=&quot;http://www.amazon.com/Service-Oriented-Design-Ruby-Rails-Paul/dp/0321659368&quot;&gt;Service Oriented Architecture with Ruby on Rails&lt;/a&gt;, presented on how to create web service clients using ActiveModel to scale an app. This is not scaling an app for traffic, but how to scaling as complexity and team size grow. Paul demonstrated how to leverage ActiveModel to implement client models with validations, dirty tracking, callbacks and even persistence. If you are struggling to deal with complexity in a large application and to abstract components into separate services, Paul offers an excellent approach. Definitely look out for his book this August.&lt;/p&gt;
&lt;p&gt;The last talk of the day, Scaling to Hundreds of Millions of Requests, was presented by &lt;strong&gt;James Golick&lt;/strong&gt;. In this talk, James outlined how he improved performance and scaled a very active &lt;a href=&quot;http://fetlife.com/&quot;&gt;community site&lt;/a&gt;. James shared his experience moving from Amazon EC2 to physical hardware and the immense performance increase this brought. James also went over his trials with MongoDB and using MySQL &amp;#8220;non-relationally&amp;#8221; with &lt;a href=&quot;http://friendlyorm.com/&quot;&gt;Friendly&lt;/a&gt; before finally settling on Cassandra. As James argued in &lt;a href=&quot;http://jamesgolick.com/2010/3/30/what-does-scalable-database-mean.html&quot;&gt;a recent blog post&lt;/a&gt; Cassandra is one of the NoSQL databases that truly scales horizontally. Look for James speaking further on this topic at Railsconf.&lt;/p&gt;
&lt;p&gt;The final hour of the conference comprised of &amp;#8220;Rejectconf,&amp;#8221; a round of lightning talks and a chance to speak for people whose talks weren&amp;#8217;t accepted for the conference program. Some highlights were Pat Nakajima presenting his &lt;a href=&quot;http://bookmarklets.heroku.com/&quot;&gt;Bookmarklet Factory&lt;/a&gt; (&amp;#8220;how to downvote 100 Gizmodo comments&amp;#8221;); Edward Ocampo-Gooding presenting on &lt;a href=&quot;http://www.openottawa.org/&quot;&gt;open data in Ottawa&lt;/a&gt;; Aaron Quint presenting on &lt;a href=&quot;http://github.com/quirkey/jim&quot;&gt;Jim&lt;/a&gt;, a JavaScript manager, bundler and compressor; and Michael Bernstein presenting on &lt;a href=&quot;http://github.com/soveran/ohm&quot;&gt;Ohm&lt;/a&gt;, the Redis object mapper with an &lt;a href=&quot;http://github.com/sinefunc/ohm-contrib&quot;&gt;extensive contrib collection&lt;/a&gt;. Then it was beer time.&lt;/p&gt;
&lt;p&gt;In all it was a great conference. Thanks to the conference organizers and hello to all the folks I met. And hello to all the folks I didn&amp;#8217;t get a chance to meet but wish I had. Keep your eyes peeled on &lt;a href=&quot;http://www.goruco.com/&quot;&gt;the conference site&lt;/a&gt;; videos will be posted in the next two weeks.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Up and Running With LaTeX</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2010/05/13/latex.html" />
   <updated>2010-05-13T00:00:00-04:00</updated>
   <id>http://akahn.net/2010/05/13/latex</id>
   <content type="html">&lt;p&gt;Recently I&amp;#8217;ve had the pleasure of getting acquainted with LaTeX. For those that don&amp;#8217;t know, LaTeX is a typesetting system that turns marked-up text files into precise, readable, print-ready documents. LaTeX is specialized for creating technical documents containing math and equations, but it&amp;#8217;s also well-suited for any structured document. LaTeX is not just the command-line tool for procesing &lt;code&gt;.tex&lt;/code&gt; files, though&amp;#8212;it&amp;#8217;s an entire ecosystem consisting of libraries, packages and tools for myriad purposes. The size of this ecosystem is staggering. At times, it&amp;#8217;s frustrating. But I&amp;#8217;ve grown to appreciate it the more I&amp;#8217;ve learned.&lt;/p&gt;
&lt;p&gt;What&amp;#8217;s so great about LaTeX? I love that it demands explicitness. It doesn&amp;#8217;t try to guess what you mean. Want a hyphen? Use -. Want a slightly longer dash, suitable for numerical ranges? That&amp;#8217;s --. Using a dash for punctuation? --- inserts an em dash. The same explicitness applies to quotes. How does LaTeX know what is an opening quote and what is a closing quote? You tell it. Use two backticks (``) for an opening quote and two apostrophes for a closing quote (''). These are two examples of the attention to detail that LaTeX promotes.&lt;/p&gt;
&lt;p&gt;Some things are more automatic. Hyphenation, for example, is handled by LaTeX. And it&amp;#8217;s smart.&lt;sup class=&quot;footnote&quot; id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; The system sometimes misses possible hyphenation points, but it&amp;#8217;s very good at avoiding incorrect hyphenation, such as &amp;#8220;new-spapers.&amp;#8221; It also allows manual control of hyphenation. For example, put &lt;code&gt;\-&lt;/code&gt; in the middle of a word to identify a possible hyphenation point. I also found some of these &lt;a href=&quot;http://www.personal.ceu.hu/tex/breaking.htm&quot;&gt;line breaking commands&lt;/a&gt; helpful.&lt;/p&gt;
&lt;p&gt;LaTeX excels at working with tables, references, bibliographies, footnotes, indexes (and math, of course)&amp;#8212;features whose use ranges from tedious to hellish in word processing software. Perhaps its greatest strength is that unlike word processing software, LaTeX forces authors to focus on the content and structure of a document, rather than its presentation. LaTeX takes care of what it looks like. It&amp;#8217;s the anti-&lt;acronym title=&quot;What You See Is What You Get&quot;&gt;&lt;span class=&quot;caps&quot;&gt;WYSIWYG&lt;/span&gt;&lt;/acronym&gt;.&lt;/p&gt;
&lt;h3&gt;Installing LaTeX&lt;/h3&gt;
&lt;p&gt;The easiest way to get started with LaTeX on Mac OS X is to install &lt;a href=&quot;http://www.tug.org/mactex/2009/&quot;&gt;MacTeX&lt;/a&gt;. Once you have MacTeX installed, take a look in &lt;code&gt;/usr/local/texlive&lt;/code&gt; (MacTeX is a specialized version of the TeX Live distribution) to see what was installed. You&amp;#8217;ll want to add &lt;code&gt;/usr/local/texlive/2009/bin/universal-darwin&lt;/code&gt; to your &lt;code&gt;$PATH&lt;/code&gt;. Also make note of &lt;code&gt;/usr/local/texlive/2009/texmf-local/tex/latex&lt;/code&gt;&amp;#8212;this is where you&amp;#8217;ll install additional LaTeX packages.&lt;/p&gt;
&lt;h3&gt;The Memoir Class&lt;/h3&gt;
&lt;p&gt;You can get far with LaTeX&amp;#8217;s built in document classes: book, report, article, etc. But for my document, I needed a bit more flexibility. I turned to the Memoir document class. The goal of this class is to combine LaTeX&amp;#8217;s built-in book class with some of the more common packages that help customize the design of a document. The result is a large class, but one that offers convenience, since it reduces the need for installing additional packages.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s difficult to summarize what Memoir offers because it does so much. Instead, I&amp;#8217;ll just share my own experience: Memoir made laying out my document a breeze. I continually got the impression that the creators of Memoir had thought of everything. Refer to &lt;a href=&quot;http://mirror.ctan.org/macros/latex/contrib/memoir/memman.pdf&quot;&gt;Memoir&amp;#8217;s exhaustive, 500-page manual&lt;/a&gt; (&lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt;) to learn about what it offers. It&amp;#8217;s epic.&lt;/p&gt;
&lt;p&gt;To install Memoir (or any document class or package), &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/latex/contrib/memoir/&quot; title=&quot;download the memoir document class&quot;&gt;download it from &lt;span class=&quot;caps&quot;&gt;CTAN&lt;/span&gt;&lt;/a&gt;, compile it using the instructions in the &lt;span class=&quot;caps&quot;&gt;README&lt;/span&gt;, and then copy the entire &lt;code&gt;memoir&lt;/code&gt; directory to the installation directory mentioned above. Then, after running &lt;code&gt;texhash&lt;/code&gt;, you should be able to compile documents using the Memoir class.&lt;/p&gt;
&lt;h3&gt;Printing 2-Up&lt;/h3&gt;
&lt;p&gt;The document I was preparing was a long packet of reading. I wanted to print this document with two pages per sheet, as a photocopied packet from a book would be layed out. Although there are ways to bend LaTeX&amp;#8217;s strong desire to print one logical page per physical sheet of paper (among these are &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/latex/contrib/booklet/&quot;&gt;&lt;code&gt;booklet&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/latex/contrib/twoup/&quot;&gt;&lt;code&gt;twoup&lt;/code&gt;&lt;/a&gt;), a more prudent alternative is pdfpages. pdfpages is a package for embedding&amp;#8212;you guessed it&amp;#8212;&lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; pages into LaTeX documents. Conveniently, it has the ability to embed multiple pages of a &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; document into a single page of a LaTeX document. The end result: multiple logical pages per physical sheet. After producing a &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; of your original document, create another LaTeX document which embeds the compiled &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt;, manipulating it to render two &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; pages on one LaTeX page. Some code might make this clearer:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;latex&quot;&gt;&lt;span class=&quot;k&quot;&gt;\documentclass&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;[landscape]&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;article&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\usepackage&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;pdfpages&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;\begin&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;document&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\includepdf&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;[nup=2x1,pages=-]&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;my-document.pdf&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\end&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;document&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The document class used here is irrelevant, but it&amp;#8217;s important to set landscape orientation. The interesting line here is the &lt;code&gt;\includepdf&lt;/code&gt; directive. The &lt;code&gt;nup=2x1&lt;/code&gt; tells pdfpages to place two pages from the &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; file side-by-side in our document. &lt;code&gt;pages=-&lt;/code&gt; tells pdfpages to include all pages of the &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; file. When you compile this document, the output contains two logical pages laid out on a landscape-oriented physical sheet.&lt;/p&gt;
&lt;p&gt;For optimal 2-up printing, you&amp;#8217;ll need to adjust your original document&amp;#8217;s margins. LaTeX assumes that you are printing a book, and thus need a large inner margin (where the binding would be) and a smaller outer margin. Memoir makes it easy to override these defaults:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;latex&quot;&gt;&lt;span class=&quot;c&quot;&gt;% Set inner and outer margins to .5 and 1 inch, respectively&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\setlrmarginsandblock&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;.5in&lt;span class=&quot;nb&quot;&gt;}{&lt;/span&gt;1in&lt;span class=&quot;nb&quot;&gt;}{&lt;/span&gt;*&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;% Set top and bottom margins to .8 inches&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;\setulmarginsandblock&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;{&lt;/span&gt;.8in&lt;span class=&quot;nb&quot;&gt;}{&lt;/span&gt;.8in&lt;span class=&quot;nb&quot;&gt;}{&lt;/span&gt;*&lt;span class=&quot;nb&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;% The {*} parameter tells LaTeX to use the measurements&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;% provided rather than attempt to calculate a ratio&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;pdfpages has numerous options for arranging booklet-style documents, which you can read about in &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/latex/contrib/pdfpages/pdfpages.pdf&quot; title=&quot;pdfpages manual&quot;&gt;its manual&lt;/a&gt; (&lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt;). &lt;a href=&quot;http://www.ctan.org/tex-archive/macros/latex/contrib/pdfpages/&quot; title=&quot;download pdfpages from CTAN&quot;&gt;Get the package here.&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Better Typography&lt;/h3&gt;
&lt;p&gt;One point of frustration I had with LaTeX was its font handling. The routine for preparing a typeface to be used with LaTeX was so elaborate that it scared me away. But then I came across XeLaTeX, a project that brings modern, convenient typography to LaTeX.&lt;/p&gt;
&lt;p&gt;Using XeLaTeX solved two problems for me. One was using Unicode characters in my documents. For some reason, LaTeX doesn&amp;#8217;t support this by default, requiring external packages for this purpose. Using XeLaTeX, it was as simple as using Unicode characters in an &lt;span class=&quot;caps&quot;&gt;HTML&lt;/span&gt; document. XeLaTeX also makes it dropdead simple to use any OpenType or TrueType typeface installed on your system. Replacing LaTeX&amp;#8217;s handsome but staid &lt;a href=&quot;http://en.wikipedia.org/wiki/Computer_modern&quot;&gt;Computer Modern&lt;/a&gt; with the dignified, refined &lt;a href=&quot;http://en.wikipedia.org/wiki/Baskerville&quot;&gt;Baskerville&lt;/a&gt; was as simple as &lt;code&gt;\setmainfont[Mapping=tex-text]{Baskerville}&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Editing LaTeX in Vim&lt;/h3&gt;
&lt;p&gt;The &lt;a href=&quot;http://vim-latex.sourceforge.net/&quot;&gt;Latex-Suite&lt;/a&gt; plugin for Vim is a lifesaver. It provides syntax highlighting, folding (handy for hiding sections or chapters you&amp;#8217;re not currently working on) and numerous mappings that I haven&amp;#8217;t taken the time to learn. One exception is the mapping for compiling. To compile your document to &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt;, use &lt;code&gt;,ll&lt;/code&gt;. The compilation log is displayed in a preview window, and any compilation errors pop up in a QuickFix window. To set Latex-Suite to use xelatex to compile your document, add &lt;code&gt;let g:Tex_CompileRule_pdf = 'xelatex -interaction=nonstopmode $*'&lt;/code&gt; to your &lt;code&gt;.vimrc&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;Further Reading&lt;/h3&gt;
&lt;p&gt;There&amp;#8217;s a lot more. This post is the tip of the iceberg. If you&amp;#8217;re interested in learning more, here are some resources that might help:&lt;/p&gt;
&lt;ul&gt;
	&lt;li&gt;The &lt;a href=&quot;http://en.wikibooks.org/wiki/LaTeX&quot;&gt;LaTeX Wikibook&lt;/a&gt; is a thorough, clear, and well-organized reference guide to LaTeX. I found the sections on formatting and tables particularly helpful.&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.lyx.org/&quot;&gt;LyX&lt;/a&gt; is a &lt;span class=&quot;caps&quot;&gt;WYSIWYM&lt;/span&gt; (&amp;#8220;what you see is what you mean&amp;#8221;) graphical editor for LaTeX. This could be a more approachable entrée into LaTeX for folks that don&amp;#8217;t want to work with plain text.&lt;/li&gt;
	&lt;li&gt;The #latex channel on Freenode has been a helpful and friendly resource. It&amp;#8217;s not just scientists and mathematicians in there.&lt;/li&gt;
&lt;/ul&gt;
&lt;p class=&quot;footnote&quot; id=&quot;fn1&quot;&gt;&lt;a href=&quot;#fnr1&quot;&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/a&gt; &lt;a href=&quot;http://tug.org/docs/liang/&quot;&gt;Frank Liang&amp;#8217;s 1983 dissertation&lt;/a&gt; should give you a sense of how much thought and effort has gone into hyphenation in LaTeX.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Notes on Redis: Data Modeling, Hashes, and Namespaces</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2010/03/30/notes-on-redis.html" />
   <updated>2010-03-30T00:00:00-04:00</updated>
   <id>http://akahn.net/2010/03/30/notes-on-redis</id>
   <content type="html">&lt;h3&gt;What is Redis?&lt;/h3&gt;
&lt;p&gt;Redis is a simple database. It stores its data in memory and saves a snapshot to disk in the background periodically. It can be used as a simple key-value store like Memcached, but it also supports more complex data types such as lists, sets, sorted sets and hashes. These will come in handy. Redis is versatile and is used for a plethora of tasks: &lt;a href=&quot;http://github.com/defunkt/resque&quot;&gt;as a job queue&lt;/a&gt;, as a cache store, for &lt;a href=&quot;http://gist.github.com/296921&quot;&gt;tracking downloads of Ruby Gems&lt;/a&gt;,  for &lt;a href=&quot;http://vanity.labnotes.org/&quot;&gt;storing A/B testing results&lt;/a&gt;, and even as the backend for &lt;a href=&quot;http://try.redis-db.com:8082&quot;&gt;a chat server&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Redis has been receiving a lot of praise lately and is the subject of lot of excitement online. This praise is deserved – it&amp;#8217;s an excellent piece of software. I&amp;#8217;ve had the pleasure of using Redis recently and here are some of my findings.&lt;/p&gt;
&lt;h3&gt;Our Use Case&lt;/h3&gt;
&lt;p&gt;On &lt;a href=&quot;http://mediafail.com&quot;&gt;mediaFAIL&lt;/a&gt;, we wanted to track how many mentions a fail receives on Twitter. We wanted to show a count of a fail&amp;#8217;s Twitter mentions and roll that number into a fail&amp;#8217;s votes – this feature lies somewhere between &lt;a href=&quot;http://act.ly/&quot;&gt;act.ly&lt;/a&gt; and &lt;a href=&quot;http://tweetmeme.com/&quot;&gt;Tweetmeme&lt;/a&gt;. Couldn&amp;#8217;t we just store each tweet in our &lt;code&gt;votes&lt;/code&gt; table? Perhaps. But this would break our &amp;#8220;user has many fails through votes&amp;#8221; association. How do I store this data in Redis?&lt;/p&gt;
&lt;h3&gt;Data Modeling&lt;/h3&gt;
&lt;p&gt;My first pass at the problem took advantage Redis&amp;#8217;s sets. For each fail that was mentioned on Twitter, I created a set containing the users that mention a fail. So, key &lt;code&gt;fail:1:tweets&lt;/code&gt; contained the set &lt;code&gt;['alexanderkahn', 'levjoy', 'TimKarr']&lt;/code&gt;. Since elements in sets must be unique, I wouldn&amp;#8217;t have to worry about a user making multiple mentions of a fail getting counted more than once. This was an elegant solution: it allowed looking up the number of mentions a fail has received using &lt;code&gt;SLEN&lt;/code&gt; (set length) and retrieving all the Twitter usernames for a fail using &lt;code&gt;SMEMBERS&lt;/code&gt; (set members).&lt;/p&gt;
&lt;p&gt;As I continued work on this feature, I realized that I wanted to link to the specific tweet where a Twitter user mentioned a fail. One way to do that would be to set a string key for each member of a set that corresponds to a member of the &lt;code&gt;tweet:1:tweets&lt;/code&gt; set. So, for the above example, I would also set &lt;code&gt;fail:1:tweet:alexanderkahn&lt;/code&gt; to &amp;#8220;12330508057&amp;#8221;, the tweet ID for my mention of the fail. But this would cause a lot of keys to be created and mean that looking up usernames and tweet IDs for a fail would require a great deal of queries for a popular fail. Thanks to Redis&amp;#8217;s new hash data structure, there was a cleaner way. In a hash, I can store both the username and the tweet ID under the same &lt;code&gt;fail:1:tweets&lt;/code&gt; key. The hash for this key would look like &lt;code&gt;{&quot;alexanderkahn&quot; =&amp;gt; &quot;12330508057&quot;, &quot;levjoy&quot; =&amp;gt; &quot;12330508067&quot;, &quot;TimKarr&quot; =&amp;gt; &quot;12330518057&quot;}&lt;/code&gt;. Since hash keys have to be unique, a Twitter mention can&amp;#8217;t be counted twice, just like with a set. Now I can look up how many mentions a fail has received with &lt;code&gt;HLEN&lt;/code&gt; (hash length) and fetch both usernames an tweet &lt;span class=&quot;caps&quot;&gt;IDS&lt;/span&gt; with one &lt;code&gt;HGETALL&lt;/code&gt; (hash get all) query. Groovy.&lt;/p&gt;
&lt;h3&gt;Redis and Ruby&lt;/h3&gt;
&lt;p&gt;The Ruby library for Redis, written by Ezra Zygmuntowicz, is a pleasure to use. It has certain touches that make it feel like Redis was born for Ruby. One example of this quality is &lt;a href=&quot;http://github.com/ezmobius/redis-rb/blob/master/lib/redis/client.rb#L395-407&quot;&gt;how it handles Redis&amp;#8217;s &lt;code&gt;MULTI&lt;/code&gt;/&lt;code&gt;EXEC&lt;/code&gt; transactions&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;multi&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;foo&amp;#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;incr&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&amp;#39;baz&amp;#39;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;In the above code, if an exception is raised during the execution of the block, none of the operations inside are committed. This is just a basic transaction like ActiveRecord provides when working with a &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; database, but is neatly implemented in idiomatic Ruby. The block returns the result of each Redis operation in an array.&lt;/p&gt;
&lt;p&gt;Another nice Ruby touch is the way the library translates a Redis hashes into a Ruby hashes. When retrieving the entire contents of a hash using &lt;code&gt;HGETALL&lt;/code&gt;, rather than returning a flat list (1. key, 2.value, 3. secondkey, 4. secondvalue) as the Redis internal protocol does, the library &lt;a href=&quot;http://github.com/ezmobius/redis-rb/blob/master/lib/redis/client.rb#L72-74&quot;&gt;turns this list into a Ruby hash&lt;/a&gt; using &lt;code&gt;Hash::[]&lt;/code&gt;. I had never run into this way of creating a Ruby hash out of an array, but its use here struck me as clever. Check out &lt;code&gt;ri Hash::[]&lt;/code&gt; for more on this.&lt;/p&gt;
&lt;p&gt;Another good project for working with Redis in Ruby is &lt;a href=&quot;http://github.com/defunkt/redis-namespace&quot;&gt;redis-namespace&lt;/a&gt; by Chris Wanstrath. This library helps you compartmentalize your Redis keys to keep different sets of data separate. We&amp;#8217;re using this to keep tweets, described above, separate from our A/B testing data. To use it, you just interact with a &lt;code&gt;Redis::Namespace&lt;/code&gt; object rather than a &lt;code&gt;Redis::Client&lt;/code&gt; object.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;namespaced&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Namespace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:my_feature&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Interact with namespaced Redis as you would a normal Redis client:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;namespaced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;bar&amp;quot;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;namespaced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;namespaced&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [&amp;#39;foo&amp;#39;]&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# The actual key in Redis is prefixed with our namespace:&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;*&amp;quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [&amp;#39;my_feature:foo&amp;#39;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Nice of Chris to take care of that for us, no?&lt;/p&gt;
&lt;p&gt;One last note. How am I accessing Redis from within my Rails app? Currently, I&amp;#8217;m taking &lt;a href=&quot;http://github.com/qrush/gemcutter/blob/redis/config/environment.rb#L12&quot;&gt;a page out of Nick Quaranto&amp;#8217;s book&lt;/a&gt; and setting a global variable (in &lt;code&gt;environment.rb&lt;/code&gt;):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;vg&quot;&gt;$redis&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Redis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# Or a namespaced equivalent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This variable provides access to Redis from anywhere in the application. This is not necessarily the best way, but for now it works. I&amp;#8217;m happy to hear how I could improve upon this.&lt;/p&gt;
&lt;p&gt;If you haven&amp;#8217;t had a chance to explore Redis yet, I recommend doing so. I hope this post helps push you in the right direction. Some handy resources will be the &lt;a href=&quot;http://code.google.com/p/redis/wiki/CommandReference&quot;&gt;Redis command reference&lt;/a&gt;, &lt;a href=&quot;http://masonoise.files.wordpress.com/2010/03/redis-cheatsheet-v1.pdf&quot;&gt;this &lt;span class=&quot;caps&quot;&gt;PDF&lt;/span&gt; cheat sheet&lt;/a&gt;, and following &lt;a href=&quot;http://twitter.com/antirez&quot;&gt;@antirez&lt;/a&gt;, Redis&amp;#8217;s author, on Twitter.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>A Sinatra App Wrapping Flickr, Plus HTTP Caching and Heroku</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2010/02/22/sinatra-app-wrapping-flickr-http-caching-heroku.html" />
   <updated>2010-02-22T00:00:00-05:00</updated>
   <id>http://akahn.net/2010/02/22/sinatra-app-wrapping-flickr-http-caching-heroku</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://recent-work.estherswhite.net&quot;&gt;&lt;img src=&quot;/images/recent-work.jpg&quot; title=&quot;Screenshot of Esther S White: Recent Work&quot; alt=&quot;Screenshot of Esther S White: Recent Work&quot; /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;In the last several months, &lt;a href=&quot;http://www.estherswhite.net&quot;&gt;Esther&lt;/a&gt; has produced a large number of monotype prints at a local printmaking studio. She&amp;#8217;s been sharing her work online by scanning it and posting it to Flickr. Recently she experimented with using Tumblr to create a stylish gallery of this work. But this process &amp;mdash; scanning, adding metadata, uploading to Flickr, followed by posting each piece to Tumblr &amp;mdash; proved to be laborious. So we sought to streamline this workflow, hoping to eliminate a step or two.&lt;/p&gt;
&lt;p&gt;Titles, descriptions, tags and sets are all easy to manage on Flickr. What if there was a way to take advantage of Flickr&amp;#8217;s great management interface, taking images and metadata and putting them on an external site? I took on this problem with a &lt;a href=&quot;http://github.com/akahn/recent-work.estherswhite.net&quot;&gt;Sinatra application that wraps the Flickr &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; in a warm embrace&lt;/a&gt;. The app makes an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; request to Flickr asking for all the images from Esther&amp;#8217;s &lt;a href=&quot;http://www.flickr.com/photos/estherswhite/sets/72157622782141504/&quot;&gt;printmaking photoset&lt;/a&gt; and renders them as thumbnails, each image linking to a page for that image. On the individual image page, the app requests information on an image &amp;ndash; title, description, and the next and previous image &amp;ndash; and displays this information along with a larger image of the piece. Now, Flickr itself is the &lt;span class=&quot;caps&quot;&gt;CMS&lt;/span&gt; and the gallery is just a pretty shell for information already stored on Flickr. No more managing metadata in multiple places. &lt;a href=&quot;http://recent-work.estherswhite.net&quot;&gt;Have a look at the site.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;What about performance? Isn&amp;#8217;t it slow to make an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; request to Flickr for every visit to the site? This is a definite concern: making an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; call to Flickr and then responding takes the application about 500ms &amp;ndash; respectable but not exactly speedy. But the content of the site is basically static. Once an image is uploaded and described on Flickr, it is unlikely to change. This means I can cache the entire page with a gateway cache&lt;sup&gt;1&lt;/sup&gt;. To do this, I set &lt;code&gt;Cache-Control&lt;/code&gt; headers that say that my pages are allowed to be cached for long time, and the cache, Varnish, serves up a static representation of the page that the app produced. Once a page has been requested once, subsequent requests for that page are lightning-fast &amp;ndash; under 100ms. After six hours, the cached representation of the homepage is considered stale, and a new one will be generated. After two days, the cached representation of an individual page is considered stale. This way, updates to the photoset or changes to images do eventually get served to visitors.&lt;/p&gt;
&lt;p&gt;I should note that I&amp;#8217;m hosting this site on Heroku. It&amp;#8217;s been said elsewhere and should perhaps be obvious by now, but I&amp;#8217;ll say it again: Heroku is awesome. &lt;a href=&quot;http://docs.heroku.com/http-caching&quot;&gt;Their use of Varnish&lt;/a&gt; made it so easy to make this gallery app fast. Deploying code with just a &lt;code&gt;git push&lt;/code&gt; is seriously great. I recommend hosting an app on Heroku if you haven&amp;#8217;t before. It&amp;#8217;s easy and, for a simple app like this one, is free.&lt;/p&gt;
&lt;p class=&quot;notes&quot;&gt;1: For more on &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; caching, see Ryan Tomayko&amp;#8217;s excellent article &lt;a href=&quot;http://tomayko.com/writings/things-caches-do&quot;&gt;Things Caches Do&lt;/a&gt;&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>FakeWeb and Regular Expressions</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2009/12/16/fakeweb-regular-expressions.html" />
   <updated>2009-12-16T00:00:00-05:00</updated>
   <id>http://akahn.net/2009/12/16/fakeweb-regular-expressions</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://fakeweb.rubyforge.org/&quot;&gt;FakeWeb&lt;/a&gt; is a great way to speed up your tests and remove dependencies on external web services. Using FakeWeb is simple: specify a &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; for FakeWeb to respond to, and give it the response you expect from the request. For example:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;FakeWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Stubbed Google!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;HTTParty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &amp;quot;Stubbed Google!&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now FakeWeb will prevent your code from making an actual &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; request and instead it will return the response you specified. But what if your application makes requests to URLs with query parameters? It would be tedious to register each &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; with FakeWeb:&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;FakeWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com/search?q=fakeweb&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Stubbed Google!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;FakeWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com/search?q=excited+kitten&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Stubbed Google!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;FakeWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com/search?q=ponies&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Stubbed Google!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Thankfully, FakeWeb has a (slightly underdocumented) solution for this. Instead of passing a string to &lt;code&gt;FakeWeb.register_uri&lt;/code&gt;, pass it a regular expression (using Ruby&amp;#8217;s &lt;code&gt;%r||&lt;/code&gt; syntax to avoid having to escape forward slashes):&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;&lt;span class=&quot;no&quot;&gt;FakeWeb&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;register_uri&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;%r|http://www.google.com/search\?q=|&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:body&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;A bunch of results&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;HTTParty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com/search?q=tunisia&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &amp;quot;A bunch of results&amp;quot;&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;HTTParty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.google.com/search?q=vegan+latkes&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;# =&amp;gt; &amp;quot;A bunch of results&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;By registering a regular expression, FakeWeb will respond to any &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; &lt;span class=&quot;caps&quot;&gt;GET&lt;/span&gt; request whose &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt; matches the pattern you&amp;#8217;ve supplied. Your test suite can make requests with all different query parameters without having to register each individual &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;. This feature adds a lot of flexibility to FakeWeb and makes it feasible to stub out your application&amp;#8217;s &lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; requests, even when complex, changing query parameters are involved.&lt;/p&gt;
&lt;p&gt;For a general overview of FakeWeb, as well a some far-less-contrived examples of its use, check out Josh Nichols&amp;#8217; post, &lt;a href=&quot;http://technicalpickles.com/posts/stop-net-http-dead-in-its-tracks-with-fakeweb/&quot;&gt;Stop Net::&lt;span class=&quot;caps&quot;&gt;HTTP&lt;/span&gt; dead in its tracks&lt;/a&gt;. Also check out &lt;a href=&quot;http://github.com/chrisk/fakeweb&quot;&gt;FakeWeb on GitHub&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Pretty Feed Items with Facebook Connect</title>
   <link rel="alternate" type="text/html" href="http://akahn.net//2009/11/06/pretty-feed-items-with-facebook-connect.html" />
   <updated>2009-11-06T00:00:00-05:00</updated>
   <id>http://akahn.net/2009/11/06/pretty-feed-items-with-facebook-connect</id>
   <content type="html">&lt;p&gt;At Free Press, when a user signs a petition or shows support for our issues on one of our sites, we want them to spread the word. We want to make it easy for users to share the story they told, or the petition they signed, and to encourage others to do the same. We usually do this with links to &lt;a href=&quot;http://www.facebook.com/sharer.php?u=http://www.akahn.net/2009/11/06/pretty-feed-items-with-facebook-connect.html&quot;&gt;Facebook&amp;#8217;s &lt;code&gt;sharer.php&lt;/code&gt;&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/home?status=http://www.akahn.net/2009/11/06/pretty-feed-items-with-facebook-connect.html%20--%20Not%20too%20shabby&quot;&gt;Twitter&amp;#8217;s status parameter&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But &lt;code&gt;sharer.php&lt;/code&gt; left us frustrated with its awkward interface and lack of branding. What about the pretty updates that Facebook applications produce? We wanted a feed item that looked branded, looked good, and compelled a user&amp;#8217;s friends to also take action. This is where Facebook Connect comes in.&lt;/p&gt;
&lt;p&gt;Using Facebook Connect for this task turned out to be simple. Surprisingly simple. Here&amp;#8217;s the routine:&lt;/p&gt;
&lt;ol&gt;
	&lt;li&gt;&lt;a href=&quot;http://www.facebook.com/developers/&quot;&gt;Create a Facebook application&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel&quot;&gt;Create a file to allow cross-domain JavaScript communication&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;&lt;a href=&quot;http://wiki.developers.facebook.com/index.php/FeatureLoader.js.php&quot;&gt;Include Facebook&amp;#8217;s JavaScript library&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Write some JavaScript&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Steps 1-3 are fairly well documented in the links above. Step 4 is the interesting part. Take a look at the code below.&lt;/p&gt;
&lt;div class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;js&quot;&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AK&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;apiKey&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;de24e7cfd602218871fc8e30b3dd8a5f&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Facebook Connect is easy!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;attachment&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;Updating from akahn.net&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.akahn.net&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;caption&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;So cool!&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;media&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;image&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;src&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://akahn.net/images/shoes.jpg&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;href&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;http://www.akahn.net&amp;quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;FB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;apiKey&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&amp;quot;/xd_comm.html&amp;quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;nx&quot;&gt;FB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ensureInit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;FB&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Connect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;streamPublish&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;AK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AK&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;attachment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php/en_US&quot;&gt;&lt;/script&gt;&lt;script type=&quot;text/javascript&quot; src=&quot;/js/facebook.js&quot;&gt;&lt;/script&gt;&lt;p&gt;What&amp;#8217;s going on here? First, I&amp;#8217;m creating an object, &lt;code&gt;AK&lt;/code&gt;, to store the various pieces of data I need. This includes an &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; key, the default message that the user will be posting to their feed, along with some other bits of text, and an image.&lt;/p&gt;
&lt;p&gt;I then get the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; ready, using &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/JS_API_M_FB.Init&quot;&gt;&lt;code&gt;FB.init&lt;/code&gt;&lt;/a&gt;, specifying my &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; key and the location of my cross-domain communication file.&lt;/p&gt;
&lt;p&gt;Then I make sure that the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; has finished loading, using &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/JS_API_M_FB.Bootstrap.EnsureInit&quot;&gt;&lt;code&gt;FB.ensureInit&lt;/code&gt;&lt;/a&gt;. I pass in a function, to be executed once the &lt;span class=&quot;caps&quot;&gt;API&lt;/span&gt; has finished loading.&lt;/p&gt;
&lt;p&gt;In the function, I call &lt;a href=&quot;http://wiki.developers.facebook.com/index.php/FB.Connect.streamPublish&quot;&gt;&lt;code&gt;FB.Connect.streamPublish&lt;/code&gt;&lt;/a&gt;. I pass in the message and the attachment object that I defined earlier. If the user is logged in on Facebook, they&amp;#8217;re presented with a modal popup inviting them to post to their feed. If not, they&amp;#8217;re prompted to log in before they are invited to create a feed item. Try it out below:&lt;/p&gt;
&lt;p class=&quot;connect&quot;&gt;&lt;a class=&quot;connect&quot; href=&quot;http://www.facebook.com/sharer.php?u=http://akahn.net/2009/11/06/pretty-feed-items-with-facebook-connect.html&quot;&gt;Post to my Facebook wall!&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And that&amp;#8217;s it! It takes a lot of setup just to make one little call to &lt;code&gt;FB.Connect.streamPublish&lt;/code&gt;. But the smooth user experience and the customized, pretty feed item make it all worthwhile.&lt;/p&gt;</content>
 </entry>
 
 
</feed>


