Monday, December 31, 2007

The Problem With Zed Shaw

You have to give him credit for sheer spirit.

And I think everybody knows the Rails community isn't what the Ruby community is.

But beating the crap out of somebody in real life is just a lot more interesting than blogging about the idea of beating the crap out of somebody. All you got to do is suprise him at RubyConf.

I hate to advocate drugs, alcohol, violence, or insanity to anyone, but they've always worked for me.
-Hunter S. Thompson

Just kidding. But just in case Zed is reading this, here's the real problem with Zed Shaw: chronic anger is an unbelievably strong predictor of heart disease. Seriously. Wherever you point the finger of blame doesn't matter that much. If people rub you the wrong way like that, you just need to be someplace else.


The other problem, of course, is this: what kind of martial artist attacks in anger - even verbally? You destroy, you dominate, or you forgive. Anything else is wasted effort.

Want To Google Surveillance Cameras Everywhere?

Here you go.

Idea: Bargain-Basement Robot Helicopter

Take one of these:

and hook up a Mindstorms NXT box to the controls.

You could even send back arbitrary sensor data to the Mindstorms box via BlueTooth.

Listen To The Experts

_why the lucky stiff is making some changes to Shoes because a better programmer than him came to him in a dream and told him to.

Friday, December 28, 2007

David Flanagan Replaced By Soulless Husk

As far as I can tell David Flanagan's book on JavaScript is the only one worth that's worth a damn, and in the days before Prototype it was absolutely crucial if you wanted to do anything interesting with JavaScript at all, so I hate to be a douche here, but this is just bullshit:

Sam Ruby:I think I prefer Ruby 1.8’s non-support for Unicode over Ruby 1.9’s "support".

David Flanagan:I don’t know anything about the rexml library...I don’t understand why Matz made some of the choices he did, but they seem to work okay...I attempt to explain all this in The Ruby Programming Language which should be in bookstores in about a month...

(From Sam Ruby's blog.)

What happened to O'Reilly? They used to brag about how they would give you the straight dope even if it meant criticizing the people who invented the technology. Now they're telling us that they don't know why the creator did something, but since that person is the creator, it must ipso facto be the right thing to do.

The upcoming book has Matz as a co-author and _why as an illustrator, but honestly, this is a language made famous by opinionated software - having no opinion about its direction and evolution isn't just weak, vague, and noncommittal, it goes against the culture. And writing a book about Ruby without knowing anything about REXML is just silly. More to the point, writing a book about Ruby without learning its standard library is ridiculous.With so many books coming out of the Ruby community right now, O'Reilly could have found somebody who knew something about REXML, or indeed, someone with a background in the language, or at least someone with an opinion about it.

Given the completeness of Flanagan's JavaScript book, I'm sure his Ruby book will be useful, but when you've got Pickaxe 3 on the way and the second edition of The Ruby Way already on the market, and you're publishing something by an author you're comfortable with who isn't even a significant part of the community, I just don't know what these people are thinking. O'Reilly were really cool once. (Bear in mind, this definition of "really cool" comes from somebody who's programming and blogging at 11pm on a Friday.)

Anyway. If you're at home programming and blogging at 11pm on a Friday, you sure as hell don't want a copy of Flanagan's upcoming book, but you may like this one instead:

Parsing, writing a Lisp interpreter, generating MIDI in real time - this book is the shit.

Thursday, December 27, 2007

Back Up Your iPod With Rails

A couple years ago I bought an iPod Nano. At that time I was, to my chagrin, on a Windows box. (In my defense, I got a lot of "free" software out of that sacrifice.) Anyway, that box now lives in storage in a sort of shed in Pecos, NM. I'm currently in Pecos, visiting my parents and brother for the holidays, so I dug my old external hard drive out from under a mountain of boxes, but there are still a large number of files on this old iPod which I don't have anywhere else, and which, in point of fact, I actually legitimately bought with actual real money.

Unfortunately, Apple by default "protects" your iPod from "illegal" copying, and if you want to do some legal copying, too bad. After I upgraded to OS X, but before I bought another iPod, I wanted to swap out some of the media files on my Nano - put a few on my laptop's hard drive and pull some new ones off the laptop and into the Nano. This isn't really possible in iTunes or the Finder, unless there's some clever hack I missed. But it turns out to be effortless in either Path Finder or the Terminal - which would be great, if the files still had the names I put them into the iPod with.

However, your iPod actually renames every file you put onto it. Here's an example:


iTunes really isn't that great, and I got tired of all this silliness, so I tracked down GNUpod, a nice set of Perl scripts which return control of my lawful property to me, but, having never used GNUpod before, I wanted to backup all my files just in case.

So I whipped up a quick Rails app. You could do this entire thing just with ActiveRecord, not Rails itself, but using a Rails app gives me the ability to add a GUI at some point in future. The Rails app has just one model - MediaFile - and its primary bit of code lives not in a controller or model or even a view, but in lib. I wanted to integrate it with Rails proper, but MP4Info, one of the metadata-extracting libraries I used, isn't compatible with Unicode, which I think Rails 2 added or something - I have a cold so this whole post will be a bit head-fuzzy, as I'm head-fuzzy myself at the moment - so MP4Info lost its ability to obtain data when run from within script/console, but still works perfectly from irb.

I also cheated a little, by preparing a file list ahead of time:

find /Volumes/giles_nano/iPod_Control/Music > ~/programming/releases/mypod/backup_nano/all_files_on_nano.txt

I don't remember everything about Ruby's File stuff, and I wanted to work fast.

The other cheat I used was to create a symlink - both my iPods have spaces in their names, which was enough to confuse ID3Lib, the other metadata-extracting library my code uses. One of them also has a stupid fancy apostrophe in Unicode or something, instead of a nice simple ASCII one, so in either case, creating symlinks on the filesystem removed a ton of development busywork.

By the way, if you noticed that programming/releases/mypod part, and you started to get curious, yes, this is part of a project called myPod, but no, it's not yet released. myPod is very, very far from release-ready at this stage. Contributors and curious types welcome, of course, although you'll need to be patient. Besides the cold I mentioned, which has me barely coherent, I have very, very specific goals for the project, and less free time than I would prefer.

If you want to use this code, you'll need to tweak it somewhat. The file list is hardcoded, you'll probably want to create symlinks for your iPod(s) just like I did, and although in theory it should work for most iPods except for Shuffles, I've currently only thoroughly used it on a Nano from a few years ago. (Large parts of it are also known to work on an 80GB iPod I bought a few months ago, just before they released the iPod Classic.)

To use it, you just go to the root dir of your Rails app and enter irb - not script/console. (Again, some kind of Unicode conflict prevents this thing from running properly from within script/console.) Using the code should look a lot like this:

<macbook of doom:giles> [12-27 10:06] ~/programming/releases/mypod/backup_nano  
! irb
>> require 'lib/nano_scan' ; backup_nano("/Users/giles/Desktop/nano_backup")

Choose an appropriate backup directory location, of course.

What you will end up with is only a backup of your Nano. Nada mas. Next I'm going to see if I can get GNUpod running, but that'll probably have to wait until I get over this cold. (Pecos, NM is way up in the mountains, with snow everywhere.) The files you extract from your iPod will still have the exact same filenames they had on the iPod itself, but you'll have a fairly complete database of their metadata which you can access from Rails, either through your Web browser (if you code some views and controllers) or via script/console. So even though you won't see the song titles or album names on your filesystem, if you go into script/console, which is fine to use at this point, you can pretty easily do:

MediaFile.find_by_title("Policy Of Truth").new_filename get your Depeche Mode fix. You could even do this:

system("open -a QuickTime\\ Player #{MediaFile.find_by_title('Policy Of Truth').new_filename}") launch your song directly from within script/console. It's a one-liner, but I reduced it to a method, like this:



quicktime("Policy Of Truth")



...if you're more in the mood for Kris Kross.

However, this approach assumes uniquely-named songs, which is not always the case. It should be fairly obvious that you can extend the model to support a search interface, and that is of course planned for the future. A more practical flaw is that this approach will be useful or useless for you depending on whether or not your media files contain metadata - many do, many do not. In practice I extracted at least some metadata from all the files on my Nano, except for two .wav files. I didn't bother to figure out a way to extract their metadata, because there were only two of them, but I know for a fact that the metadata exists, because I created them both in Sonic Foundry Acid Pro many years ago, and Acid both embeds metadata in .wavs and reads it from them. On the other hand, several movie files on my 80GB iPod had no metadata at all. I mainly use my bigger iPod for watching movies on planes, so that's kind of a hassle, but otherwise it's pretty good. My media hard drive is in Los Angeles, so I'm waiting a couple days before I use this code to back up my 80GB iPod. (Backing up a 4GB Nano on a laptop is no big deal.)

Another usage caveat: this code archives your media files' included images in the database, as a temporary measure. This can trigger max_allowed_packets errors in MySQL. I set my max_allowed_packets to 16MB and the problem was solved. Obviously you might not want that on a production machine, but if you're deploying this code in production, that's a whole nother ball of wax (especially legally speaking). Hopefully it's obvious that this code is supposed to run on your local machine, not the network, but just in case, this code is supposed to run on your local machine, not the network.

Again, this is just a tool I used to prepare my Nano for conversion to GNUpod. I'm expanding "release early, release often" to "release everything." It's not production-ready software by any stretch of the imagination, but it could be useful or interesting, so if you want, go ahead and download it, play around with it, and e-mail me at if you dig it.

Tuesday, December 25, 2007

Friday, December 21, 2007

Solution To The Rails Bug Which Utility Belt Exposes

...identified, on Rails core, by Mislav Marohnić:

I found out where .irbrc is included. Stable Rails apps have breakpoint_server set to "true" in dev mode. Well, that option makes "breakpoint.rb" get included in the dispatcher, which in turn requires IRB. Commenting out breakpoint_server in environments/development.rb fixes everything.

(Mislav found this when he installed Dr. Nic's map_by_method and encountered similar explosions.)

Update: Jeremy Kemper told me on ruby-talk that this is only an issue with old versions of Rails:

Rails 2 switched to ruby-debug since ruby-breakpoint broke when Binding.of_caller went the way of the dodo

He also objected to my calling this a bug in Rails. I think loading arbitrary .irbrc code into a non-IRB app probably really is a bug, and I can compromise and call it a pitfall instead, but if it does indeed trace back to breakpoint_server, which appears to be the case, then it's a non-issue anyway for the current version of Rails.

Long story short, it's easy to avoid the conflict by commenting out breakpoint_server if you don't use it, and it should never even happen with Rails 2.0 or higher.

Why The Transformers Freaking Rocked

The old-school Transformers were awesome. I do say rocked because I'm not as enthusiastic about the new designs. I've blogged about all that elsewhere, but I think I've figured out why these toys were so great.

I'll start with my ongoing toy-related vice, which is that I still buy and build Legos. Not just the amateur robotics Legos, which are sophisticated enough that engineers are the real target market anyway, but also the anime mecha Legos aimed squarely at kids.

The new kids' Legos are pretty cool. Kids today lose out when it comes to Transformers, unless they buy them imported from Japan, but they win in the Legos department. But it's not really because they're cool that I buy them. It's because they exercise a part of my brain which it's useful for me to exercise.

It's probably safe to say that every toy exercises some part of the brain, and the question of which part of the brain a given toy will exercise is a question worth asking for any parent (or indeed any sufficiently introspective kid). The old-school Transformers exercised three parts of the brain:

1. It's a car! Where is it driving to?

2. It's a robot, which is kind of like a person! How does it interact with the other robots?

3. It transforms, so it's a puzzle. Can you figure out the puzzle, or do you need the instructions? If you need the instructions, how quickly can you graduate from the instructions? Is the method in the instructions the safest and quickest method?

By the way, the answers to #2 could get pretty damn sophisticated if you took the time to think about it. Every Transformer had an official organizational role, and some of them were unimaginably specific. Most toys for boys involve guys who can beat each other up in a variety of ways. The Transformers had that, but they also had spies, analysts, a double agent, a supply chain tactitian, and even a fuel auditor. They had different personalities and philosophies, too. How does a grizzled veteran work on a team with an idealistic pacifist?

At the same time as you're exercizing your people skills in a toys for boys way - organizing teams for goals, etc. - you're also combining the geek power of puzzle toys with the mass appeal of simpler, more action-oriented toys. This combination of possibilities gives you a toy which is much better for a kid's growing brain than, say, the GI Joe jeep which drives around shooting people, which was a Transformer's primary competitor in the marketplace at that time. But I left out something important - an element of both strategy and of choosing which way to think at any particular moment. These toys actually exercised four parts of the brain:

4. It's engaged in a war against other robots which can also turn into vehicles, so how does it decide when it needs to be a robot and when it needs to be a car? In the case of a complicated transformation, is the payoff to solving the puzzle worth the effort?

This kind of layered mental stimulation is becoming normal for kids these days, as video games and narratives alike develop in sophistication.

Designing toys is probably a much, much more important part of defining a culture than people realize. The Transformers of the 1980s still even today kind of stand as a high point in that ongoing task.

Thursday, December 20, 2007

YouTube Is Undervalued

Not in the revenue it generates, but in the opportunity it represents, and the leverage it provides to take advantage of that opportunity.

Facebook is planning to invest in screenwriter Internet startups in 2008. Very prominent people in both entertainment and high-tech see independent production firms putting their content on the Web as a serious alternative to Hollywood's traditional studio system; on the flip side of the same coin, a video startup which dumped its user-contributed content for paid content from professionals saw its ad sales skyrocket. This didn't begin with the writers' strike, but the strike accelerated it. And Vimeo has HD which puts paid iTunes movie downloads to shame.

I actually think the YouTube buy was premature, when Vimeo is so much better and the monetization really isn't there yet, but there's a lot of money there to make. Google gets its ass handed to it on a silver platter in China because the #1 Chinese search engine indexes MP3s and ID3 tags, and Google doesn't. What if Google indexed TV? What if Google indexed shows, and there was no TV?

What if Google follows Facebook's lead and invests in screenwriter startups?

To make matters worse, there is an elephant in the room: Google. It has already figured out digital distribution in a more economic and pervasive way than any traditional media company (so has Apple, by the way). Via YouTube and its other divisions, it is developing and refining ways to make money on entertainment and Wall Street, at least, buys what they are doing. Google is currently valued at over $200 billion dollars -- compare that to the Walt Disney Company at $65 billion. Now Google is working out the last piece of the entertainment puzzle: content. Once it does, it could be game over.

Entertainment lawyer Kevin Morris for the Huffingon Post. Read it.

Ryan Davis & Eric Hodel Undercover Alien Overlords Rumor CONFIRMED

I found the proof on

Randal Schwartz Contributing to Seaside's Smalltalky Awesomeness

The Programming Perl co-author's adapting YUI for Seaside.

Help! My OS X Is Not Entirely Customized Yet!

Help is just around the corner.

Wednesday, December 19, 2007

Rails Default Testing Leaks Memory

I feel that the approach Test::Unit uses is dangerous. At some point, this probably needs to be fixed for real.

Ola Bini shows how Test::Unit tests can spiral out of control and adds some code to keep them in rein.

Inspired by that, here's a self-profiling spec runner. It's just a slapdash blend of the RSpec spec command and some basic code from the ruby-prof RDocs. Save it as profiling_spec.

This gives you some extremely extensive detail. It's probably overkill. Aslak Hellesøy's simple build profiler might actually be more effective.

Tuesday, December 18, 2007

Change OS X Login Background Pic

It took several attempts before I found a method that works. In Tiger you were able to do it with a simple change to a plist file, either via a text editor, Apple's own Property List Editor, or by overwriting the file itself with a new file that happened to have the same name. In Leopard, only the manual file overwrite works, and you have to do it as sudo.

Enjoy! Because nobody wants their computer to look like a backdrop for a late-70s Journey video.

If Your Cruise Control Blew Up When You Migrated To Leopard Too's due to a bug in Leopard's svn, which blows up on non-interactive calls.

You can get around it by installing the MacPorts svn, except MacPorts Subversion blows up due to an undocumented dependency on nawk. You could in theory get around that by installing MacPorts nawk, and in fact some people have, but currently I'm getting checksum failed errors for nawk, and Giles is not one to play fast and loose with teh chexksumz.

My solution is ghetto but effective: comment out line 74 of Cruise Control's app/models/subversion.rb, which stipulates the non-interactive flag. The app runs fine without it, and boom - Cruise Control is back.

Hollywood Writers Jumping Ship For The Internet

From the LA Times.

Based on an article by Marshall Herskovitz, who jumped ship before the strike, I predicted this on my Hollywood podcast just weeks before I saw it happening in the news. Days after I made the prediction, before I had even finished polishing the podcast, Marc Andreessen, Joss Whedon, and several others had the same idea.

Facebook director Jim Breyer, a partner at Silicon Valley venture firm Accel Partners, said he was weighing deals that would rely on Facebook's platform. "It is likely we will make investments in Los Angeles screenwriter/content-oriented companies in 2008," he said.

Erlang & Robotics

A lot of people are excited about Erlang, but it's not always obvious why. Here's one reason. Erlang's great for concurrent programming, and concurrent programming is absolutely crucial for autonomous robotics; it's the fundamental technique of subsumption architecture.

Concurrent programming is (in a nutshell) just threads. Subsumption architecture is giving a robot multiple tasks, each in its own thread. A simple example would be a thread for driving forwards and a thread for driving in reverse if the touch sensor indicates you've bumped into something. Rodney Brooks' work first at the MIT Media Lab and later at his company iRobot has proven the effectiveness of subsumption architecture (Brooks invented the technique and coined the term).

Pretty much everybody knows about the Roomba, iRobot's big consumer product, but not everybody knows about their autonomous jeeps, currently driving around Afghanistan and Iraq, and proving that even illegal invasions and brutal massacres can have their upside. iRobot has an entire military robotics division. The soldiers love their robots, and iRobot's making bank.

It's kind of surprising how few people know about these machines. There was a great video on iRobot's site about the self-driving jeep, technically a John Deere Gator. The video was awe-inspiring in its innovation and hilarious in its cheeseball factor. I found and linked to it a couple years ago and it went offline in a matter of days, and back then I didn't even have many readers.

Self-driving vehicles offer pretty obvious economic advantages, especially in terms of safety and for industries like shipping. Shrinking hardware and the trans-machine Google Filesystem make it increasingly likely that autonomous robots could pack unimaginable processing power into relatively compact frames. Languages optimized for concurrent programming may not seem crucial right now, but their usefulness in future looks pretty likely.

On the other hand, Rodney Brooks was a lot cooler when he couldn't look at a picture of an Iraqi kid getting his legs torn off by a bomb and think, "Hey, my stock price is going to go up." I'm not a Christian but there's a classic line in the Bible: "What does it profit a man if he gain the world and lose his soul?" I used to admire that guy.

What The Fuck Is Wrong With Apple?


Not only do you have to go through a bunch of extra steps to get Edit In TextMate... working again under Leopard, but the entire mechanism this uses is now deprecated and they're taking it out of future versions of OS X:

The automatic loading of bundles located in InputManagers folders is now officially unsupported […] This functionality is likely to be disabled in a future release.

I've always been a Mac guy, but I was once on a Windows box for several years, and it was actually kind of a relief. With Windows, you just resent Bill Gates every single day. It's a long slow burn. It's never a big deal. With Apple, you love Steve Jobs one day and hate him the next, and it's always a big deal. A Windows upgrade will brick your box for days, but at least it isn't an emotional rollercoaster. I can't even imagine life without Edit In TextMate. It's like having my balls cut off. I love Steve, I hate Steve, I want to marry him, I want to kill him. It's a pretty emotional relationship considering I've never met the guy.

Anyway, the TextMate fix on that blog post isn't yet working for me. I like the new Terminal but I may just revert to Tiger.

Sunday, December 16, 2007

Utility Belt vs. Rails

Upgrade to Utility Belt 1.0.6 to avoid this Rails bugness: gem update utility_belt

This is kind of like a chiuhuahua taking on Godzilla - you might admire his pep but you already know how the story will end - but Utility Belt and Rails appear to be scuffling.

Orion Edwards e-mailed me about my last Utility Belt post, regarding the Rails bug:

here are my findings...

1) If you put 'require utility_belt' in your ~/.irbrc, then utility belt always gets loaded, even if you're not running irb
This is the rails bug you mention. ActiveSupport::Dependancies pulls it in, but I’ve no idea why

2) The file utility_belt/lib/interactive_editor.rb defines a method called 'edit' as an instance method under Object

3) class Class is inherited from Object, so this means that not only does every object have an instance method of 'edit', every class now has a class method of 'edit'

4) Rails marks all methods in ActionController::Base as hidden, and as hidden_actions is a class method of ActionController::Base, it applies to all controllers everywhere

5) This causes the 'edit' method to be marked as hidden. ‘edit’ is quite common in controllers

Your .rhtml template file will get called without the 'edit' in the controller ever running, so in 99% of cases, you'll get an error indicating your @item is nil.

There’s 3 fixes

1) not have utility belt in your .irbrc (boo)

2) edit the utility belt source to prevent it defining an 'edit' method on Object (I did this personally as I don’t use the interactive editor)

3) edit the utility belt source to call it ‘ed’ instead of ‘edit’ (or some other alternative)

Orion was in fact way ahead of me. I figured out the edit part of it, but I hadn't realized that hiding the controller methods would make the error messages weirder. His prediction about the @item being nil is correct - the first user to bring this to my attention, in his screencast, saw @id showing up as nil for no obvious reason.

I told Orion this and posted it in Raganwald's comments but I might as well reiterate it here - I am releasing a patch to Utility Belt which renames the method to avoid this bug in Rails, but what I really want to do is fix this bug in Rails. There's no logical reason for Rails to be loading your .irbrc unless it's running script/console. It's definitely a bug. So, although I will release a patch to UB very soon, long-term I'll be much happier if I find the bug in Rails and patch it, and long-term I think that's infinitely better for the community, since Utility Belt isn't the only piece of code out there that can go in your .irbrc, and weird bugs that are hard to track don't make life better for anyone.


You need this method. It gives you an an array of AssociationReflections, which are handy little reporting objects giving you all the stuff you're likely to need to know about an AR association class. You can find out if it's :has_many or :belongs_to, you can distinguish a regular :has_many from a :has_many :through =>, it basically makes any kind of AR magic you might need for a plugin easy as toast. (I was going to say pie, but let's face it, pie is hard compared to toast. You'd have to be drunk and retarded to fuck up toast.)

Saturday, December 15, 2007

Utility Belt: Released Version 1.0.5

Notable because it includes Hash#+ and Hash#-.

The major use case for this is untangling params in nonstandard Rails apps. For instance,

params[:object] - params[:object][:whoops]

This is useful for both legacy Rails apps done wrong and innovative Rails apps wandering outside Rails' box.

A cherry-picking system is en route which will allow you to use Utility Belt to incorporate code like this into actual projects. (Until then, copy individual files in lib.)

gem update utility_belt

One user encountered a bug in Rails that put Utility Belt in Rails' load path. Somehow Rails is loading .irbrc. I probably need to patch Rails to fix this. If you have any idea how I can do that, pleeeeeeeeease hook me up, either via the Utility Belt mailing list, Rails core, or

Snazzy Resource

Josh Kleinpeter and I wrote a cool plugin.

ActiveResource is wicked spiffy, but the reality is that the most obvious use cases all blow up like kaboom. You can't do find(:include), you can't use form handlers without a little bit of meta and a whole lotta luck, and you can't just save an ActiveResource model across the network with all its association classes...

Until now.

Snazzy Resource is a Rails plugin that allows an ActiveRecord model to instantiate and save itself - the equivalent of a create or create! - from the params you'll automatically receive by default from any ActiveResource model saving itself via PUT which happens to contain association classes. All you have to do in your receiving-end controller is:


Save as normal from your ARes client:{"attribute" => "data"}).save

And all the other magic happens for you.

Start here:

script/plugin install

Snazzy camper pic by i_y_e_r_s on flickr

(All the other saving-across-the-network magic, that is. I'm hoping to plugin-ize my ActiveResource schema dumper, and a find(:include) implementation. Stay tooned.)

Friday, December 14, 2007

Amazon SimpleDB Runs On Erlang

Just in case anybody asks you if Erlang is actually worth learning.

Utility Belt: Be Careful What You Wish For (Bug Reports & Patches)

Seems like a lot of people must be installing Utility Belt, which is obviously what I hoped would happen, because I'm getting feature requests and bug reports every day. The feature requests are exciting, the bug reports kinda nervous-making. (Probably because in the old days everything I coded was live on a public server, any time I've got anything with a bug I have this feeling of imminent disaster until the bug's resolved.)

Anyway, during the day it was released Utility Belt went from version 1.0.1 to 1.0.4 (I set my preview release as 1.0.0, carelessly, so my initial release had to be 1.0.1), and at least one new version is on the way. If it's giving you any bugs or weirdness, definitely let me know. I've set up a mailing list:

Join up if you're interested - it's the best place for bug reports, feature requests, and patches. Please accompany all patches with matching specs in RSpec, or a really logical reason why not.

Thursday, December 13, 2007

Hash Math: + and -

I wrote some simple code which allows you to use plus and minus signs on Hashes in Ruby.

From the spec:

it "should add hashes" do
({:a => :b} + {:c => :d}).should == {:a=>:b, :c=>:d}

it "should subtract hashes" do
({:a=>:b, :c=>:d} - {:c => :d}).should == {:a => :b}

I'm kinda surprised this didn't exist already.

Here's the code; here's the spec. Both are in Utility Belt's Subversion repo, and should be available in an upcoming version.

Documentation Is For Computers To Read

RSpec plus Cruise Control equals a self-verifying, interactive documentation system.

Every time my codebase changes, my documentation pings me on Campfire.

I can run my documentation as code and literally prove or disprove every word of it.

I can't remember the last time I put a comment in my code.

I don't think human-readable documentation should be allowed.

If I wanted a flame war I'd call this "Documentation Considered Harmful." But it's not really harmful. It's just irresponsible. Writing documentation in English is like handling source control by manually copying and renaming files.

Campfire Notifier for Cruise Control: v0.1.0

I created a Campfire notifier plugin for CC.rb. It's plug and play. Drop it in your builder_plugins/installed dir in Cruise Control, set your login in the YAML, and you'll get chat room updates with every svn commit, including test failure alerts.

svn checkout campfire-ccrb

You'll need the very useful Tinder gem.

class Hash ; def + ...

I don't get why this isn't already a part of Ruby.

An even simpler way to do it:

class Hash ; alias :+ :merge ; end

(The minus sign version might be slightly trickier.)

Writer's Strike May Move Video Entertainment Biz Online

A tiny trend, but an interesting one.

Video startup ditches user-generated content in favor of professionally-created content; ad sales boom.

Top producers ditch Hollywood studio system for Internet (before the strike) because it gives them creative control.

Joss Whedon and Marc Andreessen, among others, think this might be the future.

More in my Hollywood podcast.

Wednesday, December 12, 2007

Ruby One-Liner Converts Chinese To HTML Entities

That's pretty cool.

Tuesday, December 11, 2007

Utility Belt

Utility Belt is a grab-bag of power-user tricks, toys, and tech. Two command-line utilities for interacting with gigantic self-aware AIs. An unimaginable quantity of IRB tweaks, some silly, some valuable, some both silly and valuable.

Everyone needs a Utility Belt.

Utility Belt info at RubyForge.

Or just get it going:

sudo gem install utility_belt

Shoes: The API Of Mystery

I'm never quite sure what it's going to do.

(For some reason adding a left margin also hosed the line wrapping.)

Sunday, December 9, 2007

Writers' Strike Probably Deliberately Provoked

I am not an insider, but this is my opinion. Here are the reasons I can tell you about.

Photoshop Is For The Weak

It's all about Nodebox.

Saturday, December 8, 2007

Alternatives To New Year's Resolutions

The holidays are coming up, and with them the tradition of the New Year's resolution.

The last New Year's resolution I made, I was 16 or so. I resolved to become a worse person. It worked. In that respect, it was a very satisfying resolution. I wish I could say I then boldly decided the whole idea was silly and left it behind forever, but in reality, I just forgot the whole thing.

The major thing all New Year's resolutions have in common is that they very rarely happen. It's basically a tradition of not doing anything but saying you will. That's BS, and you might as well skip it.

But skip throwing out the baby with the bathwater too. The core idea of yearly cycles being a good time to reflect and set goals, that makes perfect sense.

Two things which are fun to do on New Year's Day - for certain values of "fun" - are to make a list of how you're different from who you used to be, and to make a list of stuff you want to do this year. Stuff to do should include both serious goals and fun things you've always wanted to do but never actually gotten around to, like skydiving, or playing miniature golf on LSD, or releasing a Ruby gem, or, for the serious adventurers, doing all three at the same time.

How I wish I could post a pic right here of somebody skydiving, playing miniature golf on LSD, and releasing a Ruby gem all at the same time. If you do it this year, be sure to e-mail me a pic so I can update my blog.

Resolutions are lame, but some time to look back and then decide where you're headed, that's worth doing.

Friday, December 7, 2007

Migrations: Pitfalls For Maintenance

# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more
# migrations you'll amass, the slower it'll run and the greater likelihood for
# issues).

From Rails 2 schema boilerplate.

That's why you should always use automatic_migrations.

Baby Steps

Here's a no-frills Shoes app which shows you a text version of the "Shoes in its Entirety" documentation.

Copy and paste the code here:

class Entirety < Shoes :width => 523, :height => 716 do
# teh data
ENTIRETY = YAML.load_file('samples/entirety.yaml')
# adapted from _why's book example; clunky results
entirety_hash = {}
ENTIRETY.each {|thing| entirety_hash[thing[0]] = thing[1]}

# teh dropdown
@box = list_box :items => {|thing| thing[0]} do
contents.each { |option| option.hide if option.is_a? Shoes::Stack }
instance_variable_get("@#{@box.text.gsub(/ |\&/, "_")}").show

# teh infos
entirety_hash.each do |category, text|
instance_variable_set("@#{category.gsub(/ |\&/, "_")}", stack :hidden => true do
text.split(/\n+/).each do |p|
para p

Or download it here:

The data file is here:

Wednesday, December 5, 2007

Hackety Hack Style

Awesome link from Motionographer - a digital playground for children. (46MB .mov)

Hey Kids, Don't Be Stupid

Why I'm Not Really Scared Of George Bush

It's true, he's up to some scary illegal bullshit. But I know what happens to that kind of individual. It's pretty straightforward.

You can find a simple object lesson in the greatest movie ever made:

Long story short: every so often, Pac-Man gobbles a big glow-y pill.

(The Ruby content is coming back any day now, I swear.)

rush, A Ruby Unix Shell

Tuesday, December 4, 2007

Thoughtworks Podcast!

Episode 1: Neal Ford, Jay Fields, Martin Fowler, and Thoughtworks CTO Dr. Rebecca Parsons on DSLs.

Generate Error Pages In Capistrano With ERb

Say you've got several error pages which all essentially render a partial - but because they're error pages, you don't want them to be dependent on Rails working correctly. A nice solution is to create the "partial" in ERb and have Capistrano build the static HTML when you do your cap:deploy.

This is especially useful during planned downtime, since it becomes very very easy to make precise and specific error pages, rather than resorting to the generic "We're down for unspecified reasons, and this will persist for an unspecified amount of time" approach.

Using ActionPack would seem the way to go, especially if you've used ActiveRecord outside of Rails and seen how easy it is, but ActionPack is more tightly coupled, unfortunately. You have to require both ActionController and ActionView manually, and in that order, and then require a series of internal libraries. All you're probably doing is a few variable substitutions anyway, so ERb is much more practical.

Usability: Don't Stress Me Out

I think don't stress me out is at least as important a rule of usability as don't make me think.

In fact, I think don't make me think is just a particular instance of don't stress me out.

Apple is legendary for its good design, but iTunes and the iPod have failed me on two levels here.

First, they've taken a bunch of fun, nifty sources of happy shiny infotainment holding hands and turned it into a 41-item to-do list.

Boy. Look at this guy. 41 podcasts. What a slacker. Get with the program, mister! Little Billy already finished all his podcasts, and he's in second grade.

Second, I took this screenshot after syncing my iPod with iTunes. One Podcasts says 41 and the other one says 40. It's the same group, but I listened to one podcast in that group on my iPod.

I can't find a "sync" button that syncs my podcast to-do list(s). Or a button that magically turns my to-do list(s) back into a rewarding, leisurely tangle of diversions again. I can't remember off the top of my head which of these 41 podcasts I listened to in one playback context but not the other, so my OCD is going off like crazy. It's 8:45 am on 9/11/01, and Peter Parker is hanging out with Mary Jane on the top floor of the World Trade Center. Picture Spiderman's spidey-sense at that moment. That's my OCD right now.

Forty-one does not equal forty! This mathematical contradiction could destroy the universe!

What is this muppetry?

Nothing obvious in either iTunes' Preferences, or its View Options, or in the files you can open up and hackify with XCode, will fix this. Google hasn't yet found me an easy fix either. Even with the nifty Ruby gem id3lib and the ability to cd into your iPod in the Terminal, you're stuck. iPods store this kind of data in relatively unhackable binary formats. (I say "relatively" because nothing is truly unhackable.)


First person to tell me how to do this wins my love forever and ever and ever.

Update: I've just noticed that being frustrated by bad design has become a real theme on this blog. That's probably not hugely fun to read, so I think I'll have to change that. Maybe practice Zen meditation or something. Or pick up some design work on the side. I'm not sure. I did some uber-simple design work last night, it was pretty cool. I used this tutorial to create a "Web 2.0" starburst, and used my happy nifty Wacom tablet to paint the starburst into an existing graphic.

Yay painting in Photoshop w/Wacom.

I'm going to sleep.

Monday, December 3, 2007

scsh: A Scheme Shell For Unix

Lispers rejoice!

Do Cats See God On Catnip?

What if all the hippie stories about drugs were true? What if Christianity was true too? Maybe God put drugs on earth as a kind of shortcut mechanism, so He could stay in the loop. Prayer is filing a support ticket; LSD is God's AIM login. Maybe there's a reason the human brain has cannabis receptors. Maybe it's all part of the Divine Plan. Maybe catnip is God's AIM login for cats. Maybe he has one for elephants too. Who knows?

Sunday, December 2, 2007

Snoop Doggy Dogg Video

Again with the zero tech content. But it's totally worth it.

(Although I have to point out that Cee-Lo did it first, and better. I'm so glad I decided to discover hip-hop.)

Skype: What That Orange Icon Means

This icon:

...means the phone is not hooked up to the Internet, but has call divert enabled.

Note to Skype: Have you considered TOOL TIPS? Just a thought.

OS X: Path Finder & Quicksilver

OS X ships with Finder and Spotlight, but I never use either one. It's all about Path Finder and Quicksilver.

If you're not sold on Quicksilver yet, I'll let some funky Europeans break it down for you:

Path Finder is absurdly good too. You can use it as a plug-in replacement for the Finder - the Finder will still reactivate itself from time to time, or more accurately, various apps may bring it back to life, but if you want to set up Path Finder so that it knocks out the Finder when it loads and just gives you a file browser for grownups with serious Unix power, that's a few checkboxes on the preferences pane to do.

Highly recommended.

Update: My first few days with Path Finder were mostly Finder-free; recently the Finder's been sneaking back to life, and every time I quit it, it just re-establishes itself. There are slightly more aggressive ways to shut the Finder down, but I'm not experimenting with those until I've actually bought my copy of Path Finder and gotten comfortable with it.

Nike Style: Just Do It

Flight404, probably the best Processing programmer there is, came to Processing with ActionScript 1.0 his only coding skill.

OK, maybe Jared Tarbell is the best. But Flight404 is pretty fucking great.

Amy Hoy dropped out of high school. (I am jealous.)

Pic by dave_mcmt on Flickr

Time's a-wasting.

Saturday, December 1, 2007

Bash Google One-Liner For OS X

<macbook of doom:giles> [12-01 08:35] ~
! cat /opt/local/bin/google

system("open{ARGV[0].gsub(/ /, '%20')}")

<macbook of doom:giles> [12-01 08:36] ~
! google "let me not to the marriage of true minds admit impediments"

(And a window pops open.)

Thursday, November 29, 2007

Put This In Your ApplicationController And Smoke It

def instance(conditions = :all)
  i_var = instance_variable_get "@#{model_name.pluralize}"
  i_var = model_name.camelize.constantize.find(conditions)

before_filter :instance

The idea comes from Dan Yoder.

Update: I am a crackhead. That should use ivar_set, not _get.

And Now, A Unicorn Chaser

My last post was pretty horrific, so:

Censoring Violent Images: A Weird Pattern

The video game Manhunt 2 uses very violent imagery and themes and had to be edited extensively in order to be released in the United States. Selling the game at all is illegal in the United Kingdom. There's a censorship controversy around Manhunt 2 in the video game world, which, thankfully, did not spill over the way the controversy around Grand Theft Auto 3 (from the same game studio) did.

Someone else recently saw a small censorship controversy which did not spill over into the mainstream either. Hollywood director Brian De Palma made a "docudrama" about Iraq called Redacted. The final moments of Redacted feature a montage of photographs of dead Iraqis. These are photographs which you cannot see in the news, due to the American military's control over the American press. The military restricts the movement and presence of journalists in Iraq by "embedding" them among military units - a practice pioneered by Joseph Goebbels, of the Nazi regime - and has shot at journalists who were not "embedded", including the British journalist Terry Lloyd, whom the American military killed. (The British Government conducted an investigation and found the killing unlawful).

On that level, these are photographs which are already heavily censored. However, there is a further level of censorship. I've read conflicting reports. Some state that Redacted's distributor, Magnolia Pictures, placed black bars over the eyes of the deceased Iraqis; others say that the images were removed entirely. I've seen several of these conflicting reports so my belief is that both things happened; Magnolia altered some pictures and removed others entirely.

The first thing to realize is that neither Manhunt 2 nor Redacted have gotten great reviews, as far as their merits as a video game or as a movie are concerned. This might be the reason the controversies didn't spill over into the mainstream; the Grand Theft Auto controversy, after all, revolved around an utterly fantastic game. The second thing, just as a disclaimer, I've personally always found it weird that American movies haven't censored violence much in the past, given how much sex is censored in American movies and TV. However, the violence removed from Redacted is nothing compared to what you'll see in Hostel or movies like it, and in fact one of the sequences removed from Manhunt 2 to enable its release was very, very similar to a scene in Hostel 2, which was R-rated.

But those are just caveats. Here's the interesting question. Lots of people say violent movies encourage violent behavior; but violent crime in the US as a whole has diminished in parallel with the rise in violent subject matter in entertainment. (For example, Los Angeles is on track to finish 2007 with the lowest murder rate in four decades.) Likewise, the violent subject matter in Redacted was explicitly and deliberately compiled and presented for the purpose of halting violence. Before Redacted's release, Brian De Palma was quoted in several places saying it would be the images in his movie - the same images which Magnolia removed - which would finally end the war. (Everybody knows it was similar images on national TV which ended Vietnam.)

I took out a really horrifying picture here.

Obviously, these are provocative issues, which is one reason I'm so glad I banned comments. Every question raised or implied here is interesting, but the one thing I want to draw attention to here is the possibility that maybe showing people violent images actually discourages violence. I'm not sure if it's true or not. But all the video game press touches on Grand Theft Auto, and I used to play GTA a lot. Me and my brother would spend hours on this game, and a lot of the time we wouldn't even do the missions. Nine times out of ten we'd just kill innocent people and blow up cars at random until the cops showed up, and then kill as many cops as we could - ideally with the flamethrower or the rocket launcher - until they sent in the FBI. Then the game was to see if you could outlast the FBI in a car chase, and then, if you won that "level", they brought in the National Guard. Then the game was to see how long you could stay alive with the National Guard after you.

I'm sure this sounds like an anarchist's fantasy playground, but that's the point - that's exactly what it was. It was a fantasy playground. All these video game censorship monkeys need to remember that video games aren't real. And what really makes this all relevant is that I used to drive really fast, and these days I don't. Every time I'd leave my brother's house after playing Grand Theft Auto, I'd notice myself driving the way I did in the game. These days I drive slowly and carefully and I always get guys in sportscars who aren't old enough to drink legally going insane with frustration behind me. I don't even break the speed limit.

Just something to think about.

Wednesday, November 28, 2007

My Mindstorms-Fu Is Rusty

Below, a robot which can drive around a table without falling off. Took me hours.

Tuesday, November 27, 2007

You Must Fight The Power

Lego Mindstorms Robotics On OS X: Hello World

Here's the dead-stupid overview of how to get your Mindstorms kit running on OS X.

Getting Stuff

First, build a robot with wheels powered by motors on B and C, and with the ultrasonic sensor plugged into sensor port 4.

Then download and install NXTBrowser.

Next download and install NBC/NXC. Give the NBC compiler exec permissions:

chmod a+x nbc


Then copy the code near the middle of this nice walkthrough, where it says "NXC Sample Code." Put it in a file in the same directory as your NXC install, and call it wander.nxc. Compile it into something the Mindstorms brain can handle with this command:

nbc -O=wander.rxe wander.nxc


Turn on your Mindstorms brain; go to Bluetooth and choose On. You should see the words "Turn On?". When you do, hit the orange button. Boom.

Now go to your Bluetooth settings in System Preferences. A "wizard" will walk you through the steps of connecting to the Mindstorms brain. You may have to input a simple passkey on the Mindstorms brain. You do this just by using the arrow keys and orange button. (It may be possible to skip this step; I don't know.)

Now open NXTBrowser.

Choose "Software." There's an "Upload" button at the bottom of the UI; click it and you'll get a file browser. Choose the NBC file you created, wander.rxe, and NXTBrowser will put it on your Mindstorms brain. Go to the Mindstorms brain and choose "Software Files" - you'll see "wander", which is the program you just added. Hit Run and place robot on floor; you're done!


I'm using NXC; it's a C derivative. There's a Java derivative which looks pretty great, but for me personally the frustration of attempting to build it on OS X was too much. A few people have been successful with it, however. There's also a Ruby library, ruby-nxt; although I'm big into Ruby, and I definitely enjoy it more than C, the Ruby version is based on a remote-control model, as opposed to actually putting a program in the robot's brain. If you're building arm robots I would say go with ruby-nxt instead, but for robots that run around on the kitchen floor, NXC is my weapon of choice.

Dice? Physical Dice?

In 2007?!

The Job I Want Next

For a very long time I've been easy to hire and hard to keep. This was a deliberate thing. I chose it for particular reasons, to accomplish specific goals. It did that. But I've decided to change my system entirely, and become hard to hire, but easy to keep.

As a programmer, I've worked for around 30 different companies, almost always in a short-term capacity, as a consultant or a contractor. If you include my time as a graphic design freelancer and my work as an office temp during my late teens and early twenties - yes, I was working full-time and living in my own apartment at 19 - the number of companies is probably more like 60. There are disadvantages to this, which is why I'm changing my approach, but there are advantages as well.

The primary advantage for me was that short-term work always gives you periods of downtime in-between. I used this downtime to write screenplays and novels, to make music, to read very extensively on a very wide range of subjects, and so on and so forth. A secondary advantage is that practical immersion in a very large number of working environments over the course of several years gives you a very good feel for corporate culture. I can spot signs of trouble in a company the way old sea dogs can smell a storm in the air three days before it happens.

Greek sailor on Flickr

However, during the dot-com downturn, I had a lot more downtime. I had been doing some work I really didn't enjoy - maintaining legacy Perl for an investment bank. I was extremely bored there. I had contacted a recruiter to see if she could get me a better job, and she told me I should be grateful I had a job at all - 200,000 people had just been fired in the city of San Francisco alone. Faced with the realization that I would have to either stay with the job I had or be unemployed, I chose unemployment. I packed up my things and went far away.

A camper I used to live in; my dog and my dad's dog

I figured the downturn would blow over and I'd be able to find a new job easy enough. I was right; I just massively misjudged the scale of time on which this rhythm would operate. The downturn did blow over and finding jobs did become effortless again, but it didn't happen half as quick as I thought it would. So I had a lot more downtime than I had anticipated.

During this downtime, I was able to spend a lot more time on writing and art, although there were also significant downsides - I ate less food, bought less clothes, and owned less cool electronic toys. Eventually I came back to technology, partly because I enjoy it, and partly because I enjoy owning toys and eating food. But I definitely came back with a different perspective. Learning to draw is a good example.

I painted this in 2003 or 2004

Firstly, learning to draw changed my perspective on programming because learning to draw will change your perspective on anything. If we're talking about realistic drawing, depicting actual objects, the primary skill - really the only skill - is accurate, detailed observation. That's really all there is to it. When you draw, you make tons of observations, and you only keep the accurate ones. If you practice this mode of thinking, and then apply it to code, you're going to find your code getting more succinct - more powerful, and easier to understand.

Secondly, I took several art classes simultaneously for half a year, struggling with it, then locked myself in my place for a week over winter break with a copy of Drawing On The Right Side Of The Brain and nailed it. One lesson here is that Drawing On The Right Side Of The Brain is a hell of a book, but the most relevant lesson is that working hard at something for half a year and then obsessing over it for a week is probably a lot more productive than working a short-term job for half a year and then obsessing over something else for a week.

If you need a practical experience to cement this lesson for you, ask yourself what's more productive: a marathon coding session before you work for half a year on the problem? Or a marathon coding session after you work for half a year on the problem?

When I look back on that experience today, I realize, not only had I been shortchanging myself in my artistic interests, by sandwiching them in between short-term work, I had been shortchanging myself at work as well, because none of my marathon coding sessions ever took place after half a year's work on the problem. Actually, I say none - in fact, one company, my favorite job, I stuck around for about a year - a whole year - and only left after they managed to convince me to stay a few extra months. I left, get this madness, because I was bored. But during the time at that company, I wrote the code that I'm still proudest of, to this day. I spent a long time maintaining a legacy system, and then I managed to convince my primary customer to let me rewrite it, and the rewrite was such an improvement that people started calling me a Perl guru. (It was years before I encountered the work of real Perl gurus, so for a time I even believed it about myself, but that's another story.)

To produce genuinely excellent work requires consistent, dedicated effort over time. So my theory - that alternating short-term work with artistic "vacations" would give me the best of both worlds - actually just made me a jack of all trades and master of none.

Consequently, the job I want next is not some highly lucrative, short-term consulting, nor a permanent, full-time job. I want a permanent, part-time job as a senior Rubyist. Alternating between work and art was a mistake. I want to address my artistic interests in a consistent, dedicated way, and that includes programming.

I've been looking for this in a tentative, maybe-ish way for a while now, but I've only recently figured out why it really is a good idea. If anybody out there's been wondering, gosh, how do I hire somebody like Giles Bowkett? - now's your chance. Or more accurately, up until now, every moment was your chance, because I was easy to hire but hard to keep, but this period now might be your last chance for several years. If you're a programmer with other interests, like music, art, etc., maybe you should look for the same thing. One very excellent programmer I know gets "fuck programming" phases where all he wants to do is make drum & bass. Maybe he should. Interesting things happen when programmers make music.

Anyway, I'm not going to tell other people they should do what I want to do, especially when I haven't even proven that it's possible yet, but that's the job I want next, and I will say that I'm probably not the only programmer in the world who would enjoy that kind of thing. Why would an excellent programmer get "fuck programming" phases? It's not because they don't love programming. You really can't be an excellent programmer without loving it. It's because they love other things too, and it's good to do the things you love - all of them.

Update: I got an e-mail asking, "Why not just start your own business?" Other people have asked me that as well. So, I guess it's a FAQ. My answer, from the mail:

The thing is, I'm serving two masters either way. If I do programming and art (or actually acting), I've got to think about both programming and acting. If I start my own business, I've got to think about both programming and business. In either case I'm thinking about two things. I think I'll do better if I think about two things I'm interested in, rather than one thing I'm interested in and one thing I'm not interested in.

(I am actually interested in some aspects of business, but more the management stuff than the business stuff - i.e., more healthy development practices than accounting and planning and sales.)

Monday, November 26, 2007

Psychological Neoteny: Prolonged Immaturity As An Evolutionary Adaptation In Science (And Technology)

I have a tattoo of the Decepticon logo.

I spent at least $400 on Legos this year. And there are Lego guys who put me to shame.

The mid-twentieth century saw the rise of the boy-genius, probably because a personality type characterized by prolonged youthfulness is advantageous both in science and modern life generally. This is the evolution of ‘psychological-neoteny’, in which ever-more people retain for ever-longer the characteristic behaviours and attitudes of earlier developmental stages. Whereas traditional societies are characterized by initiation ceremonies marking the advent of adulthood, these have now dwindled and disappeared. In a psychological sense, some contemporary individuals never actually become adults.

Fascinating analysis from a UK psychiatrist.

Seaside/Smalltalk Job In Vancouver

For Deepcove Labs. Posted on ruby-talk by Boris Popov.

The Long Tail (Backwards) In Blog Readership

As usual, the spike is a result of posting something that I figured nobody would ever find interesting.

I guess the moral of the story is post a lot, even if it seems random.

A Threat Decoded (Hollywood Tangent)

(This one has no high-tech content at all - sorry.)

Here's the first in a series of videos featuring speechless actors supporting the writers' strike:

The secret decoder ring, for people outside entertainment, is that the actors' union has an upcoming contract negotiation, similar to the one which caused the writers' strike, and the actors' union has had a presence at many picket lines during the writers' strike, and a very strong presence at the more high-profile events (which is kind of how it works with actors).

What this really means is that if the writers' strike doesn't end before the negotiation date for the contract with the actors' union, the actors' union will go on strike too.

It's kind of interesting, because this video appears to be a fuzzy warm "we like you guys" thing, but it's actually a multi-billion-dollar threat.

Already, the networks are hearing from angry ad-spot customers who want their money back. Companies who buy ad time from networks tend to pay in millions. Returning millions of dollars to a customer is something companies like to avoid.

Get This Book

Have you ever noticed how, instead of computers becoming smarter and smarter, like in Star Trek, more and more people have become programmers? I don't mean professionally - I mean in the sense that you can program a toaster, or a microwave, or "program" the timer on an old-school VCR.

The explanation is in here:

Also the most interesting observations on screenwriting I've ever read, and the only cogent explanation of video games. If you've got a friend who doesn't understand why you spend hours playing video games, get them this book in the upcoming holidays. It's fantastic.

Sunday, November 25, 2007

How To Customize Safari Beyond All Reason

Here's a screenshot of Safari plus my desktop:

If you use Safari, either on Tiger or Leopard, you'll notice some differences. If you're reading this in Safari right now, you'll definitely see some differences. I had to go into Safari's innards to fix an interface annoyance, and while I was there, I decided to have some fun.

To change your windows so they don't have that "oh look it's high-tech" brushed-steel texture thing going on, do this:

sudo open /Applications/

And then go to Tools > Show Inspector and do this:

Voila - the "cool" brushed silver is gone and the "awesome" drop shadow is gone too.

You can take it further than that. Do this:

ls -laF /Applications/*.tif* get a list of all the TIFF-format images used in Safari, the app. If you change all of these images and keep them at the correct size and color depth, you can probably create an entirely new visual theme for Safari if you want. I say "probably" because these edits don't always work. One thing I absolutely hate about OS X is the Help menus, so I tried to remove Safari's Help menu, and unfortunately this destroyed something important, somehow, because after that Safari refused to boot. (Luckily Interface Builder backs up your interface files when you edit them.)

However, this does bring us to the other thing you need if you're going to edit Safari: a backup Web browser.

I like Shiira the best. Geoff Grosenbach used it in a Peepcode screencast, and it's got a happy whale. The UI is also pretty cool, and smart, and comfortable, and there's even a Dashboard Widget version, but honestly, it's all about the whale. Or maybe the fish. Looking at the tail, I think it's actually a fish. Either way, it's definitely happy.

Camino is also good. I use Firefox for dev, of course, but its cursor behavior truly annoys me, so I avoid it for anything but dev. Before I figured out how to fix the interface annoyance that started this all off, I thought I was going to have to give up on Safari entirely, so I checked out some other browsers as well - Opera, OmniWeb, and Sunrise. Sunrise has the most original thinking and the least stability. I didn't really dig Opera. OmniWeb's marketing annoyed me so much that I never really spent much time on it.

Saturday, November 24, 2007

How To Fix Safari's Silly New Textarea Alert

Safari 3 improves over Safari 2 in many ways, but it totally sucks ASS in one way: if you fill out a text area field on a form and then navigate away from the page or close the window, it pops up an aggravating little alert to make sure you really wanted to do that. Apple added this because they were apparently unaware that adults use OS X too.

Just kidding. I don't know why they did it. I do know it makes using nifty auto-submitting Ajax apps a pain in the ass in Safari, where before life was good. Luckily this is really easy to fix.

First you do this:

sudo mate /Applications/

(Assuming you use TextMate.)

And then you do this:

And then, if Safari works like any sane person would expect it to, you have me to thank.

(However, if your computer suddenly explodes, it was all your fault. I am not an Apple developer, or a lawyer. Or a tuna casserole, but hopefully you knew that.)

Update: Jack Nutting told me that there's a pretty good chance you can do it an easier way:

defaults write DebugConfirmTossingUnsubmittedFormText false

and adds that "the advantage of using the defaults command (if it works) is that the setting will stick in your user account even when new versions of Safari are released." As far as I can tell, it worked, although I guess we'll have to wait til the next Safari upgrade to be sure.

Facebook Apps: The Facebook Trap

Facebook would like you to believe they are giving you a new platform. Anybody who's been on the Web for a while knows that Facebook is selling old wine in new bottles. And yet building Facebook apps can still make sense.

People like to talk about leveraging social networks, but here's what they leave out. Joining a social network takes five minutes (if that). Staying active in a social network is a full-time job. I know exactly what that's like, because I used to organize and promote nightclubs and raves. Going to a club takes five dollars. Being a clubber or a raver takes time. In fact it eats up your life (but in a good way).

Social networking Web sites aren't platforms. They're not circles of friends, either. They're nightclubs. Some people spend all their time at these things. Some people never go once. A new social network becomes hot, everybody who's everybody is there, and one day, suddenly, without warning, everyone is somewhere else. At most of them all you have to do to get in is show your ID.

There's a lot of money in nightclubs. You go to the Winter Music Conference in South Beach, FL, you can easily spend a hundred dollars just to get into one particular club one particular night. And it won't be the only club you go to that night. There's a lot of money in club music, club clothes, expensive vodka, designer drugs, laser lights, and really big speakers. The people who work that system successfully do very well by it.

But if you're building a Facebook app, you're building a sound system you can never take out of the club. Spending money on something which won't work anywhere else only makes sense if the payoff is immediate. It's not really an investment, because assuming any given social network will persist for any given amount of time defies history. These things have been growing first hip and then stale on a cyclical basis for five years. A New York Times article blamed various executives when Friendster went from hot to not, but fashion features a great deal of randomness. Criticizing upper management for being unable to predict effectively random phenomena is like criticizing them for being unable to defy gravity. It might make a lot of sense to leverage social networking applications for business purposes, but it definitely doesn't make a lot of sense to do so in a way that locks you into any one particular social network.

Some companies think building customized social networks is the answer. Some developers think OpenID is the answer. Personally, I think the smartest thing is to do what nightclub and rave promoters do. They go to other people's raves and other people's nightclubs and they pass out flyers for their own events. If you're building a Facebook app, you want to make sure it directs people to your own site, because one day Facebook won't be fashionable and nobody will be there. Like Myspace - nobody goes there, because it's too crowded.