wonko.com

Hi! I'm Ryan Grove: Sorcerer at SmugMug, lover of movies, eater of pie, connoisseur of awesome.

Older posts

Displaying items 131 - 140 of 662

Dash not-so-express

I got a mass email this morning from Dash CEO Paul Lego. It was sent to everyone who pre-ordered a Dash Express (which Dash had promised would ship by the end of February). As you might have guessed, the email contained a last-minute announcement that the units won’t actually be shipping in February:

We’ve spent the past few weeks conducting extensive product testing to assess our readiness to ship. While we’ve made a tremendous amount of progress on the product, we have a few remaining items we would like to address before we release it. We’d like to ask you to hang on for a bit longer as we complete this development work. We’re setting a firm ship date of March 27th, 2008, and are committed to doing whatever it takes to meet this goal.

Obviously I’m disappointed, since I’ve really been looking forward to the Dash Express. But I understand that they want to get things right, especially since this is their first product. I’m willing to wait a little longer for a higher-quality device.

That said, I’m angry. I’m not angry because the Dash Express was delayed or because there was no communication about the delay until the last minute; I’m angry because, in an obvious attempt to appease the disappointed masses, Dash has made the ridiculously stupid mistake of “setting a firm ship date of March 27th, 2008”.

You can’t have it both ways, guys. Either you’re committed to quality and you’re going to delay this product until you’ve got all the kinks worked out, or you’re committed to a date and you’re going to ship it—kinks and all—when that date hits. I’m willing to wait until Christmas if it means I’ll get a bug-free device, but I’m not willing to wait until March for a device that will be slightly less buggy than it would have been in February.

Blu-ray wins

Netflix just pounded another nail into HD DVD’s coffin. Here’s hoping it’s the final nail. This nonsense needs to end.

I have both a PlayStation 3 (which plays Blu-ray disks) and an Xbox 360 with the HD DVD addon drive, so I’ve been sampling both formats for a while now. It seems like the HD DVD camp wasn’t even trying. Even the biggest HD DVD releases seem like they were shoved carelessly out the door, much like those horrible first-gen DVD titles I remember watching back in the late 90’s.

I can’t actually think of a single HD DVD title I’ve rented or bought that didn’t use a hideous default menu template with generic music and a rotating studio logo, whereas most of the Blu-ray titles I’ve watched (even the ones that were released in both formats) had the well-designed custom menus I’ve come to expect from quality releases.

It also doesn’t help that some of the more recent HD DVD releases are “Web enabled”, which just means they’ll lock up your player for 10 minutes (or sometimes crash it entirely) in order to download “exciting Web-enabled content” before allowing you to watch the movie. Fuck that.

Let the code speak for itself

According to Steve Yegge’s latest epic blog rant, I’m a n00b because I like pretty code. But apparently my love for dynamically-typed languages makes me less of a n00b. I’m so confused!

Joking aside, I couldn’t agree more with his main point, which is:

I think we can learn some lessons from code-commenting: don’t try to model everything! You need to step back and let the code speak for itself.

Hear, hear!

A few more details on Thoth and Ramaze

Update (2008-03-12): Riposte has been renamed Thoth to avoid a trademark conflict. This post has been edited accordingly. Sorry for the confusion.

Aphyr asked for some technical details about Thoth, so here they are.

One of the lovely things about Ramaze, the young (but rapidly maturing) Ruby web framework I used to build Thoth, is that it provides lots of nice features to help you get things done quickly and cleanly, yet it does so without dictating that you build your application a particular way. In fact, it’s so modular and so customizable that it’ll happily allow you to use just about any template engine or ORM you prefer.

I initially chose DataMapper as my ORM layer, largely (I confess) due to its pretty website. Unfortunately, it turns out you can’t judge an ORM by its cover. I quickly became frustrated with the lack of documentation, and when the source code itself proved difficult to understand due to a severe lack of useful comments, I decided to drop it in favor of Sequel, which has much better documentation and a more mature (and better-commented) codebase. So far I’ve been very happy with that choice.

I chose Erubis as my template engine primarily due to its maturity and speed. Ezamar, Ramaze’s native (and default) template engine, was also appealing, but it can’t compete with Erubis in the performance department. In addition, Ezamar evaluates its templates as Ruby strings in order to use Ruby’s native string interpolation features. This means that # characters must be escaped when displaying user-supplied content to prevent the user from executing arbitrary Ruby code like "#{File.read('/etc/passwd')}". Ramaze now includes a helper method to do this, but at the time it didn’t, which was a factor in my decision to use Erubis.

Since Ramaze is still young, the documentation isn’t quite as complete as I would have liked. However, the source code is well-commented and very clean, and when I had learned everything I could from the documentation on the Ramaze wiki, I found that it wasn’t hard at all to figure things out by poking through the source. On the few occasions when even the source didn’t answer all my questions, manveru and the other folks in #ramaze were happy to help.

Thoth is now feature complete and ready for release. I’m just waiting on Ramaze 0.3.6 (which contains a few features Thoth uses) before I push it out the door. In the meantime, if you’d like to try it out, you can follow these instructions to install a nightly build of Ramaze and the latest Thoth code. Let me know what you think.

Same old skin, shiny new guts

After stumbling across Ramaze a few weeks ago, I knew I had finally found the Ruby web framework I’d been waiting for. It’s still young and the documentation is still sparse, but the code is so clear and well-commented (and the folks in #ramaze on freenode were so helpful) that it only took me a week or so of frenzied hacking to completely rebuild wonko.com in Ruby. You’re looking at the result.

The only significant user-visible change is that the search feature is now powered by the Yahoo! Search developer API. Try it out; I think you’ll be pleasantly surprised by how well it works.

I’ll post more about Ramaze and Thoth (my new blog engine) later. In the meantime, if you’re curious, you can find the code here.

Quicken Online rocks

Apart from a few games, Quicken is the last piece of Windows software that I just haven't been able to replace since switching to Mac OS X. The Mac version of Quicken is pretty much universally hated and is, from all accounts, a buggy piece of crap, and I have no desire to boot up a Windows VM in order to run the Windows version.

I tried a few other OS X finance apps and wasn't happy with most of them. MoneyWell was nice enough that I actually ended up buying a copy, but after a few weeks of use I discovered that it's just not as convenient as Quicken was (it also suffers from a few annoying bugs).

In terms of web apps, Mint is okay, but pretty limited, occasionally glitchy, and spammy. Buxfer is nicer, but often frustratingly slow, and still not as advanced (or as automated) as I'd like.

Somehow, while searching high and low for a Quicken replacement, I completely failed to discover Quicken Online until today. I was blown away. It doesn't have the full featureset of desktop Quicken, but it's got all the stuff I care about, wrapped in a gorgeous, responsive UI. They even officially support my new favorite browser, Safari, and there's an awesome iPhone interface for when I'm not near a computer. Within five minutes of signing up I had imported all my accounts and was ready to go.

If you haven't taken a look at Quicken Online yet, I recommend checking it out.

Code aesthetics

I’m not exactly the tidiest person when it comes to the physical world. I have two desks in my office at home; on top of one is a bunch of clutter and an LCD, keyboard, and mouse, so you might say it’s at least serving a purpose. The other desk serves no purpose other than forming the nucleus of another gigantic ball of clutter.

When it comes to code, though, I’m the most mind-numbingly anal perfectionist you’ve ever met. Ugly code—even if there’s nothing wrong with it aside from being messy—makes me depressed. It actually affects my mood. I can’t bear to look at it, much less work with it. The aesthetics of code have such a strong effect on me that I actively avoid languages that encourage or facilitate messy code and I try to avoid working with programmers who write messy code. I know this isn’t rational, especially if I want to continue to learn and grow as a programmer, but it seems to be hard-wired. I can’t help it.

One of my biggest pet peeves is when programmers fail to use vertical whitespace and descriptive comments to make their code more readable. Obviously you don’t want pages of blank space or comments on every line, but ideally whitespace and meaningful comments should be used to break up code inside a function into logical groups. This makes the code more readable in the same way that paragraph breaks make text more readable.

The following example is a more or less randomly-chosen snippet from a Ruby Flickr library I wrote a while back. Exhibits A and B are absolutely identical, except that B has vertical whitespace and comments, whereas A does not.

Exhibit A:

def sign_request(request, params)
  if @api_secret.nil?
    request.set_form_data(params)
    return request
  end
  params['auth_token'] = @auth.token unless @auth.token.nil?
  paramlist = ''
  params.keys.sort.each {|key| paramlist << key << URI.escape(params[key].to_s)}
  params['api_sig'] = Digest::MD5.hexdigest(@api_secret + paramlist)
  request.set_form_data(params)
  return request      
end

Exhibit B:

# Signs a Flickr API request with the API secret if set.
def sign_request(request, params)
  # If the secret isn't set, we can't sign anything.
  if @api_secret.nil?
    request.set_form_data(params)
    return request
  end

  # Add auth_token to the param list if we're already authenticated.
  params['auth_token'] = @auth.token unless @auth.token.nil?

  # Build a sorted, concatenated parameter list as described at
  # http://flickr.com/services/api/auth.spec.html
  paramlist = ''
  params.keys.sort.each {|key| paramlist << key << 
      URI.escape(params[key].to_s) }

  # Sign the request with a hash of the secret key and the concatenated
  # parameter list.
  params['api_sig'] = Digest::MD5.hexdigest(@api_secret + paramlist)
  request.set_form_data(params)

  return request
end

This function isn’t the least bit complicated, but Exhibit A sure makes it look like it is. Exhibit B, on the other hand, breaks it into meaningful chunks and uses comments to tell you what each bit is doing, so that a programmer unfamiliar with the codebase can see at a glance what’s happening without having to parse the actual code.

I probably spent an extra minute or two writing those comments and adding whitespace, but that up-front investment was well worth it when I found myself looking at that code again today for the first time in months and understood it instantly.

Do your future self and your fellow programmers a favor: comment your code and use whitespace to make it more readable. Only assholes and Perl programmers think cryptic code is impressive.

Why I lack sleep

For the curious, the reason my eyeballs are currently burning like they're covered in acid is that last night, after I went to bed early hoping to get a nice restful night's sleep, I was awakened from said restful sleep at 4:15 AM by my phone ringing.

Since everyone who knows my phone number also knows that I hate talking on the phone, and since the number on caller ID wasn't one I recognized, and since it was 4:15 in the goddamn morning, I naturally assumed it was some kind of emergency and at least one of my favorite people in the universe had been killed or was in the process of being killed by terrorists or Godzilla or something equally horrible. So I immediately shook off the sleep and answered:

Me: Hello?
Female voice: Hello?
Me: Hello?
Female voice: [pause] Who's this?
Me: Who the fuck is this?
Female voice: I think I have the wrong number.
Me: You think? [click]

Do me a favor, folks: if you're going to make a phone call at 4:15 in the morning, please take a moment to make sure you're dialing the right number.

Lazyweb: please fix my broken eyeballs

For at least the last five years or so, I've been afflicted with this horribly annoying condition: if I don't get an average of about seven hours of sleep per night, then sometime around mid-afternoon my eyes begin to sting as if I'm having some kind of allergic reaction, and they'll continue doing this until I sleep.

If I have several nights of bad sleep, my eyes will begin to itch earlier and earlier in the day. The only way to make it stop happening is to get enough sleep to make up for whatever sleep debt I've incurred; then the itchiness goes away and my eyes are fine. In other words, two nights of bad sleep requires two nights of good sleep in order for my eyes to get better. On the other hand, if I get consistently good sleep for several weeks, then I can get bad sleep for a few nights in a row before my eyes begin to itch. It's as if I'm storing up sleep, and when I run out, my eyes punish me for it until I repay them.

The most frustrating thing about this is that even if my lack of sleep isn't enough to actually make me sleepy, it's often enough to make my eyes hurt so much that I have no choice but to try to get more sleep (which isn't always possible if I'm, say, at work).

I've tried everything I can think of to relieve the symptoms, including eyedrops and mid-day naps, and the only thing that works is for me to repay whatever sleep debt I've incurred, which often means I can't get any relief until the weekend (and sometimes not even then if I happen to sleep badly).

Does anyone else suffer from something similar? If so, how do you deal with it, short of just sleeping a lot?