TIL Ruby ObjectSpace#define_finalizer

I ran into a situation recently where I was writing a library that utilized large files. Specifically a GTFS feed parser. I wanted to cache the files away someplace so I could safely access them for the life of an object, but I didn’t want to leave them hanging around afterwards. I couldn’t do all my work inside a block passed to Dir.mktmpdir because I was planning on accessing the cache when necessary (not just one big up front parsing operation).

This got me wondering: “does Ruby have finalizers?”. It turns out it does in the form of ObjectSpace#define_finalizer. It’s worth mentioning that there are some tricks to using them which are nicely documented on Mike Perham’s blog here

The gist of it is this: don’t create finalizers which hold a reference to the instance they’re finalizing or it just won’t work. I’m glad I found that blog post before I started coding because I would have certainly fallen into the trap he describes. It probably doesn’t help that the ruby doc examples don’t include any examples of adding a finalizer in a class definition.

So all of this works out pretty nicely and leaves me with code looking something like this:

class Source
  def initialize(source_zip)
    @tmp_dir = Dir.mktmpdir
    ObjectSpace.define_finalizer(self, self.class.finalize(@tmp_dir))
    # Dump contents of zip into tmp dir

  def self.finalize(tmp_dir)
    proc {FileUtils.rm_rf(tmp_dir)}

GitX and Lion

Currently GitX does some funny things in OS X Lion like opening two windows every time you launch the app. This is easily fixed with the following:

defaults write nl.frim.GitX ApplePersistenceIgnoreState YES

I tweeted about this a while ago with appropriate credit to this tweet. But finding it again in my twitter stream was a pain so here it is for posterity.

Quick Font Reset for MacVIM

When my eyes are tired, or if I want to put my feet up on my desk and relax while still coding I usually bump my VIM font up way high. This is nice and easy with MacVIM because the standard OS X keyboard shortcut applies (Command+Plus). The problem is, when I’m ready to go back to my normal font size I have to hit Command+Minus a bunch of times or source my .gvimrc to get back to the normal font size

I was in the middle of doing this today when I thought “man, it would be nice if I could hit Command+0 like in other apps and go back to the standard font size”. Then I realized I was using VIM and I could do that. So here ya go:

nnoremap <D-0> :set guifont=Meslo\ LG\ M\ DZ:h10<CR>


Tpope Owns My ~/.vim Directory

Some people might clean their house on the weekend… I cleaned my ~/.vim directory out. What’s this? Have I ever used that? I must have just downloaded that because someone said it was cool. All is neat and tidy now, but in doing this cleanup I got a reminder of how useful tpope’s work is. His plugins dominate my setup. Not only that, but they are some of the most often used. Thanks, Tim!

Cool GitX Feature

GitX shows you stage buttons for chunks of changes in a file it thinks go together which usually works out fine. What’s cool is that it also allows you to select lines with your mouse and stage them too. WIN.

Trying Out MacRuby & Hotcocoa


You could download/install MacRuby from the site, but I chose to stick to my normal ruby workflow and use rvm. So…

rvm install MacRuby

Some tutorials linked to from the MacRuby site seem to indicate that hotcocoa is bundled with MacRuby. Unless I’m doing something wrong, that’s not the case anymore. You can install the hotcocoa gem easily enough though:

gem install hotcocoa

What’s cool here is that with a standard (non-rvm) setup you would have had to do something like:

sudo macgem install hotcocoa

But because we’re using rvm it takes care of that for us.

Generating the Application

This step is similar to any other application generator just pass in the name of you application to the hotcocoa command:

hotcocoa DoubleRainbowApp

The first thing I did after generating the application was to add a .rvmrc file to the directory that looked something like this:

rvm MacRuby

Now we don’t have to worry about switching to MacRuby when we’re working on our MacRuby project. The .rvmrc file will automatically switch us the MacRuby whenever we cd into the project directory.

Getting Into Tmux

I had tried out screen on OS X and failed to make it stick with me as a day to day tool, but recently I started using tmux and can’t imagine going back. Some of the things that set tmux apart are it’s ability to do vertical splits w/o any screwy patches and scriptability.


So lets start with the basics, installation.

brew install tmux

You can surely install this other ways, but using homebrew is super easy and you should be using it anyway.

Settling In

Like any tool there is some stuff that I got into the config file right away to make it feel more homey. First, I switched out the default command prefix C-b for C-a. From what I’ve read the only reason C-b is the default is so that it doesn’t conflict with scree. C-b is torture for your fingers though so there’s no reason to stick with that.

set-option -g prefix C-a

Next, because I use vim as my editor, I told tmux to us vi mode keys.

setw -g mode-keys vi

Finally, I setup some bindings so that I can move around splits using the vim movement keys.

bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

That’s it. That’s everything in my ~/.tmux.conf right now. Like I said I just started with tmux so I’m sure my customizations will grow but as a vim user this is what I needed to make tmux feel more like home.

Basic Operation

As I got into using tmux there was definitely a point at which I learned just enough so that I was comfortable using it all the time and didn’t think to myself “Why am I using this, if I was using straight terminal I could do x so easily”.

Here’s the rundown of my most used commands…

Note: I use C-a in all the examples below, but if you have a different prefix set up substitute that for C-a.

Creating a new session from the command line:

tmux new -s my_session_name

Creating a new session from within a running session:

C-a :
new -s my_session_name

What’s cool here is that while in tmux you can hit C-a : and get a tmux command prompt and execute any of the normal tmux commands.

Attaching to running session:

tmux attach -t some_session_name

or if you know you only have one running session just:

tmux attach

Creating new windows while in a session:

C-a c

Naming your current window

C-a ,

Switching sessions:

C-a s

Entering copy-mode:

C-a [

A note on copy-mode… I kind of think of this as entering normal mode in vim.Being in copy mode allows you to move around the terminal just like normal mode in vim. To be honest, I’m pretty sure I’m not using copy-mode to it’s full potential yet. I mainly use it to scroll up to see things that have gone out of view in my terminal window.

My RDoc Setup

I used to keep rdoc and ri turned off to speed up gem installs via my .gemrc config. This became problematic recently when I was planning on doing some work while traveling, and knew I wouldn’t have an always on internet connection to get my documentation fix. I recalled a github page to install the template. No big deal, just drop the github username from the gem install command like this…

gem install hanna

The “hanna” template absolutely kills the default rdoc template. You’ve probably seen it around being used by various projects and there’s no reason not to use it locally.

Next I updated my .gemrc to ignore ri and to use the “hanna” template for rdocs.

gem: --no-ri
rdoc: --inline-source --line-numbers --fmt=html --template=hanna

Finally I re-generated my rdocs by running:

gem rdoc --all --overwrite

I ignored the rest of the steps in the aforementioned post as I don’t really feel the need to be running a passenger instance just to serve rubygems docs. I generally just run gem server whenever I need to access my local docs.

My solution is barely more than what you get out of the box with rubygems but with just a few changes I find myself much happier with my local docs.

Readability for Sane Online Reading

If Readability isn’t in your bookmark menu bar, then there is something missing. I’ve been using arc90’s Readability bookmarklet for a while now and thought it was probably a well known thing, maybe I was wrong. Last night I showed it to some people at the B’more on Rails Open Source Hack Night and no one had heard of it before. So, if you’re ever bothered by reading news online surrounded by ads and extraneous content check it out.


Deploying Sinatra With Passenger on Dreamhost

If the following is true:

  • You want to deploy a Sinatra application with Passenger on Dreamhost
  • You’re using a Dreamhost shared hosting account
  • You’re application relies on gems that aren’t installed globally on Dreamhost
  • You’ve got the gems you need installed locally like this

Then you’ll want to include something like this in your rackup file:

ENV['GEM_HOME'] = '/home/<dreamhost user name>/.gems'
ENV['GEM_PATH'] = '$GEM_HOME:/usr/lib/ruby/gems/1.8'  
require 'rubygems'

This will make sure your locally installed gems will be available to your application. Maybe my google skills are getting rusty, but it took me a while to find this solution. Here’s the original source.