from the desk of michael nutt

English Ordinal Suffix

As I was previewing the post published yesterday, I realized that the post's date was marked as January 31th, 2009.  Looking through my templates, I saw that I had been lazy and hard-coded "th" into the template.  Investigating further, I discovered that strftime (the method that Liquid Templates use to format dates) had no way to output the correct suffix.

There didn't seem to be any clean place to put it in the layout or in LimeSpot, but LimeSpot happens to let you add arbitrary javascript to your pages so I added this little snippet:

  <!-- hack -->
  <script type="text/javascript">
    $$('.post_date').each(function(date) {
      var day = date.select('.day')[0];
      var modDay = day.innerHTML % 10;
      var suffix = 'th';  // default case
      if(modDay == 1) { suffix = 'st'; }
      if(modDay == 2) { suffix = 'nd'; }
      if(modDay == 3) { suffix = 'rd'; }
      date.select('.th')[0].update(suffix);
    });
  </script>

The Empty Browser

Yesterday I was reading the Mozilla Labs Blog where they were talking about removing chrome and making the browser controls take up less screen space.  I wanted to explore it more, so as a first step I removed Firefox's chrome piece by piece to see how it affected my browsing experience.

The Home button? I have never clicked it before.  My browser opens to whatever page was opened last.  Easy decision.

The Stop button. I don't often stop pages loading, and in the few cases where I do I use escape out of habit.

Reload? I use it a bit more, but I'm pretty accustomed to Ctrl-R and I think I can deal.

Next, the Back/Forward keyhole buttons.  I use Alt-left and Alt-right arrow more than I use the actual buttons themselves, but what I found is that the Back and Forward buttons are the only things giving me visual indications that I can go back or forward.

Removing tabs is like going back to the year 2000.

With the status bar gone, I am totally lost.  Like walking around in a dark room bumping into things, I can't tell if a page is loaded, or loading, or perhaps stalled.  I suppose I could get used to gauging how long pages take to load, but it's definitely an inferior browsing experience.

In conclusion, it's not as easy as just removing all of the buttons. (not that anyone ever said it was)  Being an Emacs user I may like using the keyboard more than most people, but the visual cues I that I get from the buttons are more important than the buttons themselves.  It would be very easy to remove the vertical scroll bars in Emacs because the keyboard is the preferred device for navigating through the page, but many people leave them in because they give a visual indication of the length of the document and location of the cursor in relation to the rest of the document.

Fortunately, I think it's easier to provide visual cues than to provide buttons for people to click. I intend to keep an eye on these new de-cluttered browser developments.

Rethinking Car Design

I just ran across this brilliant new idea from BMW:

Why do we need metal bodies for cars, anyway? Assuming that a carbon fiber frame is just as sturdy as a regular steel frame with regular panels, I can't see any reason you would.  Washing might be difficult, but I'd imagine you could just take the fabric off and throw it in the wash.  Five years down the road when it's not looking so great, just buy a new cover for a couple hundred bucks.

Will this revolutionize the car industry? Probably not any time soon at least, but hopefully it'll get things moving in that direction.

Rails routing and namespaces

A while back, Rails gained the ability to namespace routes.  For instance, if you wanted to add a blog to your app but didn't want to pollute its top-level URL space, you could do this:

namespace(:blog) do 
  map.resources :posts
  map.resources :tags
end

Then you get a nice blog at "/blog" and everything is great, right?  You now have to put your post blog controller in app/controllers/blog/posts_controller.rb, and put your views in app/view/blogs/posts/.  It seems clean, but it turns into so much typing that it gets annoying.  When rendering partials explicitly, you have to add the "blog/" prefix.  Worse, you now have to append "blog_" to every named route helper you use.

Namespaced do happen to be great for disambiguation, however.  Admin interfaces are a perfect example: you can put your exposed blog controller in app/controllers/blogs_controller.rb and put your admin blog controller in app/controllers/admin/blogs_controller.rb.

I made the mistake of namespacing a number of controllers because I thought it would make for a cleaner grouping, and I am paying for it in the time I have to take to de-namespace.  The moral of the story is to only use namespaced routes when :path_prefix => "/blog" won't work.

mod_rails

The webserver stack for Rails-based projects changes every 6 months or so.  First it was apache+fastcgi, then lighttpd+fastcgi, then apache+mongrel, then nginx+mongrel.  Our production servers for limespot.com are using nginx+mongrel, but there's a new deployment option out now: Phusion Passenger, otherwise known as mod_rails.

At last week's hackfest I decided to try out mod_rails to see how easy it was.  The website advertised it as the easiest deployment option, so here it is:

Installation is really as simple as gem install phusion-passenger and then passenger-install-apache2-module while following its instructions.  I'm using Leopard so I already had apache and simply edited /etc/apache2/httpd.conf and added the three required lines.

From there it got a little bit weird.  I think mod_rails' ideal use in development would be to be able to point it to ~/Sites and have it rails-ify each of the sub-directories.  I tried setting Apache's DocumentRoot to /Users/michael/Sites, but mod_rails didn't pick up the sub-directories as rails apps.  I had to link each public directory to my webserver's DocumentRoot and use the RailsBaseURI directive in order to manually specify each rails app.

The first rails app I tried was my company's intranet app.  I was quickly presented with a beautiful error page telling me I had failed.  It wasn't very helpful, but wow did it look good!  It wasn't hitting rails at all and the only apache log message was "define INLINE_DIR or HOME in your environment"  ImageScience was to blame, and I never could figure out how to get it to find INLINE_DIR on its own.

I figured I would go ahead and try LimeSpot, and to my pleasant surprise it just worked (mostly).  Rails' stylesheet caching didn't work properly, but after I turned it off the stylesheets came down just fine and everything was rewritten with the "/limespot" prefix.  Our custom mongrel handlers didn't work, obviously, so it will be a while before LimeSpot switches to mod_rails.

All in all, mod_rails is looking to be a really promising deployment solution, even in a development environment. It would be great if it could be made to detect all rails projects in a directory and automagically serve them from subdomains or subdirectories.

Update: mod_rails supposedly supports Rack now, though I haven't looked into it.

Graduation

IMG_3825.JPG

 I went down to Houston this weekend to see my brother graduate.  It was hot.  I've only been to Houston a couple of times since he started school, and it seems like only recently that I was helping him move into his freshman dorm.  Surveying his new apartment, I began thinking of all the trade-offs that one makes living in New York—cramped apartments, dirty streets, and alternating cold/hot weather.  I still think they're worth it.

The Bleeding Edge

I've spent a few evenings hunting down a particularly annoying bug in my latest rails app.

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):     /vendor/rails/actionpack/lib/action_controller/ request_forgery_protection.rb:73:in `verify_authenticity_token' ...

I was trying to get a script.aculo.us sortable list working, and I spent tons of time debugging with Firefox + Firebug to try and figure out why the authenticity token wasn't getting passed.

Firefox 3 includes tons of great new features and it requires a new Firebug, so every couple of days I'm getting the latest alpha release of Firebug.  For some reason I was sure my rails app was broken, rather than Firebug.  As a matter of fact, it turns out my rails app was working just fine and Firebug was lying to me and resubmitting the request when I tried to use it to check out the response. (score: Rails CSRF protection 1, my sanity 0)

I fixed it by either turning on Firebug's new debugging mode, or turning on its network monitoring.  I can't really tell which because I can't seem to figure out which one actually solves the problem. 

These nifty development tools are great, but sometimes there is no substitute for inspecting outgoing TCP packets.

Feeds

For the first time, my blog now has an RSS feed.  Welcome to 1999!

Spread Thin

In some ways I don't like being spread broadly around the web, in the sense that all of the content I use is hosted all over the place at a number of sites.

I'm not even a prolific creator of content.  I don't take as many photos these days, I don't record video, and I rarely find time to write new blog entries.  What I do have: blog entries on nuttnet (which is really LimeSpot), tweets on twitter, photos on flickr, old entries on livejournal, a single video on youtube, stuff behind the facebook walled garden, and other content that I can't even remember posting.

Read More »

SXSW

I suppose it's a bit late, but I'm down in Austin at South By Southwest this year.  Come say hi at our party tonight.

The Magic is Temporarily Unavailable

And that's what I get for neglecting my own theme while building other peoples'.  The cobbler's children have no shoes.

Firefox Clutter

Confession: I used to use Windows as my main operating system, and for a long time I used Internet Explorer as my browser.  As a 14-year-old, I always saved my money to buy as much memory as I could, because at any given time I'd have 20 or 30 browser windows open.  When I discovered Firefox and tabbed browsing, I dropped down to 5 or 10 browser windows, but they had 10-20 tabs each.  My room was also cluttered as a kid.

Now I use Mac OS with only a single Firefox window, but I still have entirely too many tabs open.  This mostly results from links appearing outside the browser, such as links in instant message windows and emails.  I usually open these links once, look at the page, then forget about them.  It would be really nice if I could specify one of Firefox's tabs as a "junk tab", to be reused for all external links.

I can't think of a clean way to fit the feature into Firefox's user interface, but I'm looking forward to the new bookmark management system. 

Moving

I just shut down the Athlon64 server sitting in my living room.  Suddenly the room goes quiet. I could hear crickets chirping if such things could survive in New York.  The quiet is disconcerting; I begin to wonder if the steady hum of the fans is all that has kept me sane for the last year and a half as I sit alone in my old apartment.

Challenge

IMG_0084.JPG copyToday I was invited at the last minute to a challenge of epic proportions.

I'm not usually one to participate in eating competitions, but macaroni and cheese is one of my favorite foods ever (yes, I'm still four years old) and I gave in to old-fashioned peer pressure. Secretly I was planning on only eating half and taking the rest home, but one thing led to another and I ended up finishing the "Mongo" size. So did Nathan, and he finished first.

We were rewarded with nothing but pride, though the waitress did give me a free water for finishing.

Apartment Hunt

IMG_0064.JPG copyI've nearly secured an apartment.  It's in the East Village, and it's quite nice.  It's cozy (read: small) but also cozy in that it just feels nice.  The bedroom has no windows so that's going to be weird, but I think I'm just going to sleep with the door open.  I have one final thing to do tomorrow morning and it's mine.

Of course, as with anything in New York there's a chance that it'll slip through my fingers and I'll have to go back to looking through craigslist and calling brokers.  I think New York requires a certain fortitude that is most heavily tested during relocation.

At least I'm not buying a house. 

Primary

I voted today.  You should too, unless you're Canadian, a convict, or generally disenfranchised.

The nearest polling place was a school a few blocks from me, which was incredibly hot and humid, especially considering the nice 50-degree weather we're having in New York.  I was not on the list.  I ended up having to go back to my old polling place in Prospect Heights, where the smell of freshly baked chocolate chip cookies from the school cafeteria made me very hungry and not particularly politically inclined.

Last night a coworker pointed me to Lawrence Lessig's  video on why you should vote for Barack Obama.

How I Got Here

I was only vaguely familiar with LimeWire in college. The career center at my school basically gave me two options: go to work for one of those mind-numbingly boring local government contractors that showed up to the career fairs, or go to grad school. Our school had an online job board filled with the previously mentioned government contractors, but in the middle of listings by Raytheon and Lockheed-Martin I noticed a Ruby on Rails position listed by Lime Wire.

"Those guys are a company?"

I've since gotten that question more times than I can count at career fairs and info sessions. People generally seem to think that either LimeWire was written by some nerds in their basements, or that it just appeared one day through some sort of Intelligent Design.  Maybe the internet created it.

I had a very nice chat with Justin Schmidt, who asked a bunch of algorithms questions, described the design of Limespot, and got me very interested in the project. At the time I was interested in Rails, but was still new to it. For whatever reason he invited me up to New York for an interview.

Since Lime Wire was my first real interview ever, there were a few things I hadn't yet learned. I flew myself up to New York and slept on a friend's floor out on Long Island the night before. The day of the interview I woke up very early and took the two hour train ride into New York City. Being the confused tourist I was, I mistakenly got off at the 23rd street subway stop, and walked approximately 30 blocks through the pouring rain. By the time I got there my shoes made squishing noises as I walked, and I was soaked from the shoulders down.

Fortunately I made the correct judgment not to wear my Interview/Wedding/Funeral suit that my parents had given me, and instead opted to wear jeans. At least I was comfortable during the strenuous day-long interview. As I left the interview, I was sure that there was no way Lime Wire would hire me. I think I might have even failed the reverse-a-string question at one point. I nearly even declined the dinner invitation as to not waste any more of their time. Two weeks later, I had the job.

From the outside, I saw the Lime Wire interview process as a Really Big Deal. I kind of imagined it like a trial, where the interviewers interrogated me, analyzed the laws, and made some sort of ruling. In retrospect it's just a bunch of regular people trying to find the best co-workers they can.

One year and two months later, LimeSpot is a reality.

Limespot.com has launched!

It's finally live!  After over a year of working on it, limespot.com has gone online.  It powers blog.limewire.com, also.
Loading Plugin
Loading Plugin
Loading Plugin
Loading Plugin

Valid HTML 4.01 Strict