Alieniloquent


Living In the House That Rails Built

January 29th, 2008

I wanted to share a snippet of code. This code will print a call stack to STDOUT every time a Ruby class definition is evaluated. It is particularly useful when you find that class constants are being mysteriously redefined.

class Foo
  puts "\nRequired from:\n  #{Kernel.caller.join("\n  ")}"
  # ...
end

What inspired me to write that code? Rails did. The key to writing Ruby on Rails is that you’re writing Ruby on Rails. You don’t follow the Rails best practices because they’re convenient. You follow the Rails best practices because your program won’t work unless you do. Just like trains, you stay on the track and everything is great. If you try to take your train off-track, then it’s gruesome enough to make the nightly news.

How did I derail my application such that I cared how and where a file was being required? I wrote a unit test that explicitly required a model object. Oops. Remember that the semantics of require is load-once based on the name. So:

require “foo”

and:

require “models/foo”

are very different to require. Rails is super helpful and requires everything that it makes for you. So it requires models for you, even when you run your unit tests.

So take this code:

class Foo < ActiveRecord::Base
  RAILS_IS_A_GHETTO = true
end

And then write a test for something that Rails didn’t generate (such as something in the lib directory like I did):

# Require some other stuff
require "foo"

class TestTruth < Test::Unit::TestCase
  def test_truth
    assert true
  end
end

If you rake test you will get an error complaining that RAILS_IS_A_GHETTO was reinitialized, and that’s because Rails loads it for you as “models/foo” and you load it as “foo” so it gets loaded twice.

The moral of the story is: let Rails load the things it built, and you load the things you built.

Making Terminal Bearable

January 3rd, 2008

I’ve been using Macintosh computers for several years now, but I came to them from the Unix world. There were several expectations I had from my terminal emulator. Among them were that the key that says Alt on it should be my Meta key for Emacs key-chords, and that the Page Up and Page Down keys should page up and page down in my application. None of those behaviors are the default, so fixing them is one of the first things I do when I get a Mac.

In Leopard these settings are all in the Settings section of Preferences (Cmd-, or Terminal > Preferences…), but in previous versions they are in the Window Settings screen (Terminal > Window Settings…).

First, to take care of the Alt key issue, go to the Keyboard section of the settings. There is a checkbox toward the bottom that says “Use option key as meta.” Check it.

With that problem solved, all that is left are the paging keys. The default behavior is to have Shift Page Up send Page Up to the terminal and Page Up and do the same for Page Down. In the Keyboard Settings you should see a grid with keystrokes on the left and text on the right. In many cases it will be an ANSI escape sequence to send to the terminal, in some cases it will be a special action. Here’s what you want to set things to.

  • page down = send string to shell: \033[6~
  • page up = send string to shell: \033[5~
  • shift page down = scroll to next page in buffer
  • shift page up = scroll to previous page in buffer

That effectively just swaps the keys, so that you still have the ability to scroll your Terminal buffer with the keyboard.

After I fix the keyboard, I like to fiddle with colors and other things, which will all be in the same preferences dialogs. Then, after all the tweaks and fixes, Terminal is ready to use.

Layout, design, graphics, photography and text all © 2005-2007 Samuel Tesla unless otherwise noted.

Portions of the site layout use Yahoo! YUI Reset, Fonts & Grids.