I found that new terminal sessions were taking a while to load, so I started commenting things out in my bash profile (How to be a Programmer: A Short, Comprehensive, and Personal Summary calls it a Binary Search). I found that it was snappy when I commented out my calls to virtualenvwrapper and rbenv.

Of course, with these calls I lost the ability to use them, and I lost the defaults. To fix this I chose a faster way to load the defaults and made functions for loading the full functionality of these. Here is the relevant part of ~/.bash_profile.

# Python
export VIRTUAL_ENV_DISABLE_PROMPT=1
# my virtualenv is called "batv", replace this with what you passed to mkvirtualenv
source $HOME/.virtualenvs/batv/bin/activate
loadvirtualenv() {
  # the next two lines might not be necessary for you; I only have them on OS X and not Linux
  export PYTHONPATH=/Library/Python/2.7/site-packages/virtualenv-1.6.4-py2.7.egg
  export PYTHONPATH=/Library/Python/2.7/site-packages/virtualenvwrapper-2.10.1-py2.7.egg:$PYTHONPATH
  source /usr/local/bin/virtualenvwrapper.sh
  workon batv
}

# Ruby
export PATH="$HOME/.rbenv/shims/:$HOME/.rbenv/bin:$PATH"
loadrbenv() {
  eval "$(rbenv init -)"
}

To use my default virtualenv or to use rbenv without the rbenv shell command, I don’t have to run either of these functions. If I want to do advanced stuff with virtualenvwrapper, I type loadvirtualenv and hit enter, and then I can use all of virualenvwrapper in that terminal session. If I want to set a rbenv environment for my current shell, I type loadrbenv.

Before I made these changes, the contents each of these functions were run each time I created a terminal. Now they’re run only on demand and opening a new terminal tab is much snappier!

I’ve been reading quite a bit about parsing and templating in ruby as I attempt to port a templating engine from JavaScript to Ruby. Here are some scattered links:

Jison

Jison is a parser generator for JavaScript that has separate lex and bnf definitions. It’s used by Handlebars.js.

Repositoryjison
Ownerzaach

Treetop

Treetop is a parser generator for Ruby. It’s installed with Ruby On Rails, through the mail gem which is installed by ActionMailer.

Repositorytreetop

Citrus

Citrus is another promising parsing gem for Ruby. It seems to be very easy to get started with, and I like many of the design decisions.

Repositorycitrus

Temple

Temple is a templating-specific library that helps with a lot of the AST transformation. It doesn’t seem to have a CFG syntax so it seems that using treetop or citrus would make sense for complex grammars. Otherwise, strscan could be used.

Repositorytemple
Ownerjudofyr

temple-mustache

This is an implementation of a mustache renderer in . It uses strscan to generate the initial parse tree, and Temple to generate the ruby code. It supports mustache sections.

Repositorytemple-mustache
Ownerminad

Slim

Slim is a Haml-like templating library for Ruby that’s used in production by many. It uses Temple, with a line-based parser, which works well because it uses significant indentation for nesting.

Repositoryslim
Ownerstonean

For the November meeting of Front Range Pythoneers we did a bowling code kata. We worked as a group on the projector, but I also worked on my own version on my laptop. Here’s my code, which was fun to write. It’s a single file which contains its test cases and can be run on the command line or imported:

import unittest

class Frame(object):
    def __init__(self, tenth=False):
        self.rolls = []
        self.tenth = tenth

    def full(self):
        if len(self.rolls) >= self.max_rolls():
            return True
        if self.tenth:
            has_special = all([roll in ('X', '/') for roll in self.rolls])
            return len(self.rolls) == 2 and not has_special
        else:
            return self.strike()

    def roll(self, score):
        if self.full():
            raise RuntimeError('attempted to record a roll on a full frame')
        self.rolls.append(score)

    def pins(self):
        if len(self.rolls) == 0:
            return 0
        if self.strike() or self.spare():
            return 10
        else:
            return sum([int(roll) for roll in self.rolls])

    def first_roll_pins(self):
        if len(self.rolls) == 0:
            return 0
        elif self.rolls[0] == 'X':
            return 10
        else:
            return int(self.rolls[0])

    def score(self, subsequent_frames):
        if self.tenth:
            return self.tenth_frame_score()

        score = self.pins()
        if self.strike():
            score += sum([frame.pins() for frame in subsequent_frames])
        elif self.spare():
            if len(subsequent_frames) > 0:
                score += subsequent_frames[0].first_roll_pins()
        return score

    def tenth_frame_score(self):
        return min(Game(''.join(self.rolls)).score(), 40)

    def strike(self):
        return len(self.rolls) > 0 and self.rolls[0] == 'X'

    def spare(self):
        return len(self.rolls) > 0 and self.rolls[-1] == '/'

    def max_rolls(self):
        return 3 if self.tenth else 2

class Game(object):
    def __init__(self, roll_scores=''):
        self.frames = []
        for score in roll_scores:
            self.roll(score)

    def roll(self, score):
        if len(self.frames) == 0 or self.frames[-1].full():
            tenth = len(self.frames) == 9
            self.frames.append(Frame(tenth))
        self.frames[-1].roll(score)

    def score(self):
        return sum(self.frame_scores())

    def frame_scores(self):
        frame_scores = []
        for frame_index in xrange(len(self.frames)):
            frame = self.frames[frame_index]
            subsequent_frames = []
            if frame.strike() or frame.spare():
                subsequent_frames = self.frames[frame_index+1:]
                added_frames = 1
                if frame.strike() and len(subsequent_frames) > 0:
                    added_frames = 2 if subsequent_frames[0].strike() else 1
                subsequent_frames = subsequent_frames[:added_frames]
            frame_scores.append(frame.score(subsequent_frames))
        return frame_scores

class GameTest(unittest.TestCase):
    def test_initial_strike(self):
        self.assertEqual(Game('X').score(), 10)

    def test_two_strikes(self):
        self.assertEqual(Game('XX').score(), 20+10)

    def test_three_strikes(self):
        self.assertEqual(Game('XXX').score(), 30+20+10)

    def test_strike_spare_strike(self):
        self.assertEqual(Game('X9/X').score(), 20+20+10)

    def test_strike_strike_spare(self):
        self.assertEqual(Game('XX9/').score(), 30+20+10)
        self.assertEqual(Game('XX9/71').score(), 30+20+17+8)

    def test_perfect_game(self):
        game = Game('X'*12)
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 300)

    def test_made_up_game(self):
        game = Game('X907/818/X70070/72')
        self.assertEqual(len(game.frames), 10)
        self.assertEqual(game.score(), 132)

if __name__ == '__main__':
    unittest.main()

I think that the tenth frame calculation is incorrect. My limited understanding of bowling slowed me down a fair bit. I got an object system that I’m fairly happy with, though!

I’m working on a project where I think I’ll be using a parser library so I’ve been looking at the options. One thing I’ve noticed is that treetop is installed when Rails is installed. I didn’t know why, though, so I looked around.

First I looked at the Gemfile.lock. Had I known the format I would have found out my answer more quickly. I didn’t, though, and so when I found my first result for treetop, I stopped. It showed treetop below specs in the hierarchy.

GEM
  remote: http://rubygems.org/
  specs:
    # ...snip...
    thor (0.14.6)
    tilt (1.3.3)
    treetop (1.4.10)
      polyglot
      polyglot (>= 0.3.1)
    tzinfo (0.3.30)
    uglifier (1.0.3)

The next thing I did was run find . -iname '*.treetop' in ~/.rbenv. It found the following results:

(mbp) ~/.rbenv/versions/1.9.2-p290 $ find . -iname '*.treetop'
./lib/ruby/gems/1.9.1/gems/erector-0.8.3/lib/erector/erect/rhtml.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/address_lists.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_disposition.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_location.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_transfer_encoding.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/content_type.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/date_time.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/envelope_from.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/message_ids.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/mime_version.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/phrase_lists.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/received.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2045.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2822.treetop
./lib/ruby/gems/1.9.1/gems/mail-2.3.0/lib/mail/parsers/rfc2822_obsolete.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/examples/lambda_calculus/arithmetic.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/examples/lambda_calculus/lambda_calculus.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/lib/treetop/compiler/metagrammar.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/compiler/test_grammar.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/compiler/test_grammar_do.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/a.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/b.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/c.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/d.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/f.treetop
./lib/ruby/gems/1.9.1/gems/treetop-1.4.10/spec/composition/subfolder/e_includes_c.treetop
(mbp) ~/.rbenv/versions/1.9.2-p290 $

Aha, so there are numerous treetop files in actionmailer! I have my answer. Seems like a good use of a parser, plus those may be worth using as examples.

Then I took another look at a Gemfile.lock from a rails project, and saw that it was plainly listed there. I just didn’t see it and didn’t keep looking after I found one.

GEM
  remote: http://rubygems.org/
  specs:
    XMLCanonicalizer (1.0.1)
      log4r (>= 1.0.4)
    actionmailer (3.1.1)
      actionpack (= 3.1.1)
      mail (~> 2.3.0)
  # ...snip...

I noticed something: Gemfile.lock doesn’t show an arbitrarily nested hierarchy; instead it shows a list of gems and their dependencies, where the list of gems includes all gems. Then, separately at the end of the file, it shows the top-level gems from the Gemfile.

To see a deeply nested, a graph could be constructed from the Gemfile.lock, using the two nesting levels under specs as an adjacency list.

In the last couple of years I’ve witnessed a disturbing trend: developers adopting free Heroku as their only means of hosting side projects. More disturbingly, I operated this way myself for a couple of years. (Yes, freemium can be a trap for customers just like it can be a trap for businesses.)

Heroku has five megabytes for database space, which often sounds like it ought to be enough when it isn’t. Want auditing and comments? Nah, that’ll take up too much space. Its single dyno free plan serves one request at a time. The next steps up are twenty dollars a month and five cents an hour for databases and dynos, respectively. These aren’t that expensive for a major project, but for several side projects it quickly adds up.

I realized this and switched back to running a VPS, this time on Zerigo, which I pay for annually. There is no limit to the number of apps I have. Concurrent requests are supported. They can use the same databases. Database backups are free and uncomplicated. I’m also happy to be outside of the cloud oligopoly that seems to be forming.

Besides that, it’s fun! I get to try niche language platforms. Node.js was building steam long before Heroku supported it, and it still doesn’t support websockets. It’s not hard to find, with a little thinking, other interesting platforms to try. How about Racket or Factor? Or setting up your own Lucene server, or a web server that uses the git command line tool? Those can’t (easily) be run with Heroku.

I find anecdotally that most developers don’t have their own websites or non-trivial side projects. I only have the first, but I can sense that my personal website is helping me prepare to launch non-trivial side projects. I’ve done very little work to set up this server, yet despite tweeting about it and having visitors and occasional commenters, it stays up. That gives me the confidence I need to launch something bigger.

My plea to other developers (and aspiring developers) out there is to draw parallels between programming and other creative works and find out how much you could responsibly be spending for hosting side projects, and then realize that there’s no reason you shouldn’t have at least a VPS.

Today I read a great post that happens to be on a Posterous blog, and I wanted to send my kudos to the author. Feeling lazy, I clicked Posterous’ version of a Like button, which is a heart with a tooltip that says “Unlike this post” when I hover over it.

A few short minutes later, I saw a comment notification in my email inbox.

Posterous has this feature where people who leave comments receive notifications when people post additional comments. This way, people will see replies to their comments.

It does the same when people like posts, though. But the main reason for wanting to see comments doesn’t exist when people like posts. People generally do not reply to likes, though I admit I’ve seen it happen once or twice.

The lesson in this is that default actions software takes should be based on user intent, and that this is especially important when it’s a loud interaction like sending an email.

I’ll go further and say that this is one of the major pros to having threaded discussions in blog comments. DISQUS does this and they’re very wise to do it. They only send me email notifications when someone specifically replies to one of my comments. If I commented on Posterous posts nearly as often as I did on DISQUS widgets I’d have email notifications turned off for Posterous comments by now.

One final note: I posted a test comment without realizing it would get emailed instantly and that I didn’t know whether or not I can delete comments on Posterous (I can’t), and it got deleted soon afterward. Apparently the blog owner was close to his email. ;)

I wrote a script to delete URLs containing a string from Chrome’s history. It works for me. I don’t understand everything that it does, though, so it may have serious flaws. Use at your own risk.

# Removing history entries from Chrome that contain a search phrase
# Exit out of Chrome first
# Back up files and do this at your own risk

# gem install sqlite3 && gem install sequel

require 'sequel'

search_string = 'reddit'

# Delete history cache files
path = File.expand_path('~/Library/Application Support/Google/Chrome/Default')
cache_dirs = Dir.entries(path).select {|dir| dir != 'History' && dir.index('History') == 0}.map {|dir| File.join path, dir}
cache_dirs.each {|dir| File.delete dir}

# Delete matching history from sqlite3
DB = Sequel.sqlite File.join(path, 'History')
matching_urls = DB[:urls].filter(:url.like("%#{search_string}%"))
puts %Q[Deleting #{matching_urls.count} urls matching "#{search_string}"]
matching_urls.delete

I really like sqlite and Sequel.

Rails 3.1 has a serialize function that can take a custom column coder. A custom coder needs to have dump and load methods set, or else it will be recognized as a required type for the built-in YAML coder called YAMLColumn.

While the JSON class has the two required methods, it doesn’t allow specifying a default. So I created a custom coder. I don’t know where the best file and module locations to put the class in are, so I won’t include them here. This is the class, though:

class JSONColumn
  def initialize(default={})
    @default = default
  end

  # this might be the database default and we should plan for empty strings or nils
  def load(s)
    s.present? ? JSON.load(s) : @default.clone
  end

  # this should only be nil or an object that serializes to JSON (like a hash or array)
  def dump(o)
    JSON.dump(o || @default)
  end
end

Since load and dump are instance methods, an instance of JSONColumn needs to be passed rather than the class. Here’s an example that works for me inside of the rails console:

class Person < ActiveRecord::Base
  validate :name, :pets, :presence => true
  serialize :pets, JSONColumn.new([])
end

Update: Added .clone to the load method. HT @miyagawa.

I just googled something I’ve always wanted to know how to do in vim, and was surprised how quickly I found the answer.

In vim, there are separate modes for searching and commands. This generally works well as they have separate completion buffers and since I do them a lot, it keeps my command history from cluttering up my search history and vice versa. The area where I’ve wished that they were unified is when I want to convert from a search to a substitution expression. Normally in vim you do search expressions in search mode and command expressions in command mode. For example, if I wanted to search for trailing whitespace I might type:

/\s\s*

If I want to replace it with an empty string through the whole file I might type:

:%s/\s\s*//g

I can’t remove the / at the front of the command line with a backspace and replace it with a colon, so until I learned the tip I’m about to reveal I had to retype it. No longer.

The StackOverflow answer I found for the query, Convert vim / search to search and replace without retyping regular expression, suggests this remarkably simple technique:

You can type

/search_term

and then

:%s/<ctrl-r>// etc

where you actually press ctrl+r and then / to insert the search term.

It works! No longer do I desire for search and command modes to be unified.

There’s nothing new about expressing XML in a significant-indentation format. Here’s Slim next to one from 2001.

Simple Outline XML (2001)

html>
    head>
        title> My Home Page
    body>
        h1> Contact Details
        p>  I can be contacted at
            a>  href=mailto:me@myplace.net 
                this address
            except when on vacation.

Wikipedia Article

Slim (2010)

html
  head
    title My Home Page
  body
    h1 Contact Details
    p I can be contacted at
      a href="mailto:me@myplace.net" this address
      except when on vacation.

They’re quite similar. I find Slim a bit more comfortable in a ruby environment because it’s a bit more terse and uses two spaces like Ruby code does. It also is a templating language too. (In fact, I’m not sure there are converters going in both directions between XML/HTML and non-templated Slim. It could make a nice addition.)

I find vim’s :lcd command to be quite useful. For a long time I didn’t use it, mainly because I didn’t understand how it works.

First, using it is simple. It works just like :cd. You type :lcd path/to/directory in command mode. The path is relative to the current directory, so :lcd .., :lcd ~/Desktop, and :lcd /etc/apache2 all work.

The :lcd command changes the path of the current window. The current window is the current frame within the current tab. Now, what’s really neat, is that a new window (created from commands such as :sp and :tabedit) gets the local directory of the window it’s created from.

Most plugins respect it. Both Command-T and ack.vim search within the local current directory. Another plugin, fugitive, bases its commands on the git repository of the current file so it works smoothly with different local directories as well.

Bang commands (like :!cp README.md ~/Desktop) also use the local current directory.

Finally, after using it for a while it gets easy to tell which directory I’m in. The status line displays the path of the current file based on the local current directory, so if I know where the current file is I can quickly figure out where the local current directory is.

I used it the other day with bundle show to dig through the source of two dependencies of my Rails project to better understand them.

If you use vim and haven’t got in the habit of using :lcd I highly recommend it. If you use another editor and wish it handled working in multiple directories gracefully, consider giving vim a shot!

…and I like the new .on() and .off() API for setting up events.

I wrote some code that uses it, just for practice.

$.fn.tree = function(data) {
  var $el = $(this),
      html = [];
  
  function renderNode(node) {
    if (typeof node === "object") {
      html.push("<ul>");
      for (var key in node) {
        if (node.hasOwnProperty(key)) {
          html.push("<li><strong>" + key + ": </strong>");
          html.push(typeof node[key] == "object" ? renderNode(node[key]) : node[key]);
          html.push("</li>");
        }
      }
      html.push("</ul>");
    }
  }
  
  renderNode(data);
  $el.html(html.join(""));
  
  $el.on('click', 'strong', function() {
    $(this).closest('li').find('ul').toggle(200);
  });
};

$("<div>").appendTo("body").tree({
  name: {
    first: "Benjamin",
    last: "Atkin"
  },
  location: {
    city: "Boulder",
    state: "CO"
  },
  accounts: {
    social: {
      twitter: "http://twitter.com/benatkin",
      facebook: "http://facebook.com/atkin",
      gplus: "http://gplus.to/benatkin",
      identica: "http://identi.ca/benatkin",
      rstatus: "http://rstat.us/bat"
    },
    creative: {
      github: "http://github.com/benatkin",
      blog: "http://benatkin.com/"
    }
  }
});

Nothing too fancy.

Repositoryjquery
Ownerjquery