american flag

Sometimes the mac shows a tiny american flag in the menubar. This bothers me. I don't want to think about the United States of America and all the issues surrounding the american flag every time I check the time in the menubar. I certainly don't want to program myself with the jingoism that (these days) images of the flag connote.
The way to turn this off is to go to the International preference pane and uncheck "Show input menu in menubar."

My new hosting provider,, textdrive was down for two days. Today dreamhost (which serves up download.openlaszlo.org and Scott Evans' blog went down for eight days straight. Jumpline hasn't ever had any downtime that I noticed, in three years of using it, but there webapp for controlling things was really out of hand bad; the equivalent of voicemail hell. Sarah Allen likes mediatemple, but she's got some sort of relationship with the CTO... and it looks like it's down right now. I'm not sure who hosts Adam Wolff's blog, (but he'll probably see this post because I mention his name). The heavy-hitters I know host their own servers at colos. But come on, I'm just a minor netizen. I want to post my blog and some photos and some swf's. I have this illusion that maybe someday I will want to post a Ruby on Rails app, but really, it hasn't happened yet. However, I think it's crucial that my site is served from my own top-level domain. Maybe Apple has the solution; $99 a year for .mac is not bad compared to $8-$200 a month for downtime-o-rama. Apple software just makes me happy; maybe Apple hosting will, too.
And look, for the record, I can set up my own linux box for development, but I know that I don't know enough to protect a server from all the malware in the world.
I don't think my demands are particularly outrageous, except perhaps that i want all this for less than $200 a year. I'll hang out with TextDrive for a while, maybe actually get a RoR app up.
Maybe this should start being a perk that medium and large businesses can start offering to employees. Companys pay for cel phones and laptops, right? My manager has a few times suggested that I blog on one topic or another -- and the essays that turn up i our blogs are a hell of a lot more readable, opinionated, useful, and timely than the http://wiki.openlaszlo.org which does get quite a bit of atention from the OpenLaszlo team. Email is not enough, people. Corporate IT now takes it as a matter of course that they must maintain email, networking, backups, and applications. I propose that corporate IT also begins supporting the digitial lifestyle of the technorati by solving the "where do I host my blog" problem fof me.

after the move

"All your furniture doesn't fit in your new apartment!" the owner said with some dismay, seeing my IKEA POANG chair and LACK coffee table on the back patio. "No," I agreed. "Why is that?" "My last apartment was bigger than this one. It's okay though. I like it here." And I do. The owner runs a shop, and she offered to sell the coffee table for me; the POANG's cushion had been pretty well destroyed by the cats, so I think I'll just use it for outdoor furniture.
The new apartment is maybe half the size of my previous apartment, but I really think I can be happy here. Happier, even -- this might be more of the right place for me than where I was, at Money Village. I took a lot of pleasure from all the manicured landscaping at Money Village, and appreciated the latino men who were always replacing something just past its prime with something about to flower. The sprinkler system -- irrigation, really -- for the gardens bothered me a bit... Not exactly a waste of water, but a gratuitous use of it. The Columbia River died so I could look out on a rich green meadow? (I know my water really comes from the Hetch Hetchy reservoir, but it amounts to the same thing. The Hetch Hetchy valley died so I could look out on a rich green meadow.)
Where I live now is a quiet street in Pacifica, two blocks from the ocean, with rows of single-story houses. Each house has its own garden or lawn or trees, and it's all alive. There are palm trees, and succulents, and flowering vines, and weathered fences, and gravel driveways... and it's beautiful. I don't think these people have landscapers. I think they take care of their yards themselves, and plant a bush or a tree because they plan to enjoy that tree for ten or twenty years. The air is always damp with fog coming off the ocean. My apartment is half the size of my old apartment, but the owner is building a mosaic walkway to the back patio for me, and I think we might become friends. On the wall above my desk is a large-format photo she took of a desert scene; the wall is light mauve; the floor is bamboo. Everything here is here because the owners -- two people-- decided to put it here.
Money Village was a great place to live for a year, and it was a level of luxury that I needed after the scary South Side of Providence. Now I'm happy to be here, cozy and foggy and rich with the opposite of transience.

irony

"The irony is..." that George W. Bush does not know what irony is. Correct me if I'm wrong here, but I'm pretty sure that's ironic. It is also ironic, a different sort of irony closer to cynicism, perhaps tragic irony, that the leader of the most powerful nation in the world, he who holds the reigns to a military, economic, and symbolic power that could actually decrease the violence in the Middle East, is the stupidest, least-diplomatic man to hold that office since the creation of Israel as a modern nation-state.
...all of which is a simplistic analysis that, I'll grant, fails to account for many of the dozens of factors contributing to the tempest of the Middle East... But still! In my simple analysis I still feel secure in claiming this: If the US, in the person of Rice or Bush or Bolton or any of the hawks who communicate US policy to the world, would simply ask Israel to stop bombing Lebanon, then Israel would stop fucking bombing Lebanon.
This precipitating issue, the two kidnapped Israeli soldiers, brings to mind the assasination of Archduke Ferdinand... except that in this case perhaps a dozen US black-ops boots-on-the-ground and a single military helicopter venturing into Lebanon under cover of night could bring the soldiers back to Israel... But then we'd lose the pretense under which the US would, could, will invade and occupy the entire region.
Might, perhaps, the "two kidnapped Israeli soldiers" turn out to be a sham along the lines of babies pulled out of incubators in Kuwait, centrifuge rods and yellow-cake uranium in Africa, secret stashes of WMD to the "north south east and west of Baghdad," and George W. Bush's service in the National Guard? The hawks in this administration have repeatedly fabricated evidence, or expertly deployed fear/uncertainty/doubt, in order to justify their (our, damn it!) political and military actions.
I would have more respect for the neo-cons if they simply declared, to Iran, Iraq, Lebanon, Syria, Kuwait, and (heck) Saudi Arabia: "We'd like to control the middle east. Please return the keys to your country to the UN, for distribution to the western judeo-christian capitalist democracy of our choice."
Maybe fewer people would die that way.

Just switched hosts, some things broken

I switched hosting providers in the middle of the night last night (did you notice sbshine.net down for a few days? No? Good.) and now a few things are broken, most notably, archives, and a weird css error at the top of the page.
I couldn't decided between TextDrive, DreamHost, and MediaTemple, so I ended up going with TextDrive because I liked their site design best.
Anyways, I promise I will get things back up soon. I know some of you are dying to find my archived post on the rich text editor :)

making ant easier to deal with using scripts

A major complaint with ant is that it's a purely declarative language, and some build tasks really want to be expressed procedurally. Scott Evans summed this up by saying ant is a hateful language. But when I was tasked with improving the build system, I wanted to work through the hate.
Inspired by dojo, I handled some tricky parts in the OpenLaszlo ant build files by inserting small java-via-javascript script tasks. Our "old" (ant 1.5.1) files had to deal with some bend-over-backwards structures to fake procedural logic, or used <if> tasks from antcontrib. I was dissatisfied with antcontrib because it seemed abandoned, and the bend-over-backwards was hard to read, understand, maintain. The general approach I've taken here is described in the ant manual.

Consider this problem: we want to build a platform-specific installer. The ant 1.5.1/antcontrib build file looked like this:


<if><equals arg1="${build.platform}" arg2="unix"/><then>
<!-- tar up a bunch of stuff -->
....
</then><else><if><equals arg1="${build.platform}" arg2="macosx"/><then>
<ant target="pkg-dev" />
</then><else><if><equals arg1="${build.platform}" arg2="windows"/><then>
<ant target="nsi-dev" />
</then></if></else></if></else></if>

The main problem with this is that it's hard to read the semantics from all of the pointy brackets. I prefer this alternate formation, where we use javascript to just express an if/then/else procedurally:

<script language="javascript"><![CDATA[
var pkgtask = lps.createTask("ant");
if (lps.getProperty("build.platform") == "unix") {
pkgtask.setTarget("pkg-gzfile");
} else if (lps.getProperty("build.platform") == "macosx") {
pkgtask.setTarget("pkg-dev")
} else if (lps.getProperty("build.platform") == "windows") {
pkgtask.setTarget("nsi-dev");
} else {
var f = lps.createTask("fail");
f.setMessage("Unknown OS. Failing.");
f.execute();
}
pkgtask.execute();
]]> </script>

This formulation is, imho, cool. It's using ant's Java api via javascript via rhino via the Apache Bean Scripting Framework to let us express procedural logic procedurally. We can use the ant java api to get access to ant tasks, properties, and targets, but use javascript logic structures to make decisions.

Yes, it's syntactic sugar, but when I'm maintaining a build file of more than 1300 lines, I'll take some sugar if it makes it easier to read, understand, and maintain.

(BTW, it looks like there's a logic problem in my javascript; you'll still get to the final pkgtask.execute() even if you don't know the platform. But no! The else-unknown-platform case creates and executes a fail task, which pops us out of that scope, and we never get to the pkgtask.execute() line.)

(Meta-problem: examples of cases which would benefit from javascript-ificiation instead of built-in ant task composition are by definition very complicated. A small example isn't as compelling as a big one would be, but for the purposes of pedagogy, I'm using a small example.)

fat kitty vs mac

If you suffer from an excessively affectionate cat, as I do, here is a helpful tip for mac users. Go to system preferences, Keyboard and Mouse, Trackpad. Check "Ignore accidental trackpad input" and "Ignore trackpad when mouse is present." Then the cat can walk on the trackpad and hit the trackpad button and it's all okay.
A co-worker (P T Withington) pointed me at this helpful video of how to use the mac as an exercise machine for the kitty. This seems like it would be less effective with my 16-lb cats. Maybe when I someday replace my powerbook, I can devote it to a cat exercise device.

rewiring lamps

Tonight is going to end badly if I don't find some electrical tape, and fast!
I have a great ikea lamp with six halogen bulbs, but something went wrong with it: whenever I turned it on, with a little step-on switch, both of the cats immediately go stare at it. Noses less than an inch away, two large cats, staring intently at a motionless piece of black plastic. When this became repeatable, I decided the switch was bad, maybe emitting high-frequency noise or a smell I couldn't smell, and that the lamp would have to go. I really like the lamp, though. So this evening I got out my tools, snipped the cord before and after the switch, then opened up the switch. (Yes, dear parents, it was all unplugged.)
I discovered the switch was just a simple rocker, and a single cat hair was inside the mechanism, touching one of the contacts and the live side of the switch. Aha! The cat hair was conducting a tiny tiny bit of electricity, and it was heating up a tiny tiny bit, enough to make a tiny smell that only cats can smell.
This light actually plugs into an outlet with a switch of its own, so I don't need a switch; I just need to reconnect the two ends of the cord, where the switch used to be. No problem, just... oh no! where's the electrical tape?
I do not have any electrical tape in the apartment. I've got velcro and gorilla glue, but I left my electrical tape behind in Providence and haven't needed any since. My WRONG BAD DON'T TRY THIS AT HOME impulse is to make the splice without electrical tape. Thus the thought:
Tonight will end badly if I don't find some electrical tape, and fast!
I could drive to the all-night everything store and pick some up... but clearly what I really need is to hit the home depot and stock up on electrical tape and duct tape, and replace that utility knife I accidentally gorilla-glued closed last weekend. And, um, what other hardware tinkering stuff am I missing? Maybe this calls for a trip to Fry's!

my addendum to Getting Real

When working evenings and weekends, do the fun stuff.
Your tool suite (applications, languages, processes) should vary in a punctuated equilibrium. Make the changes to your tools when you are in a relative lull. Resist the impulse to learn a new tool when your current project is nearing completion, or, worse, when it's nearing a deadline but not nearing completion.

TextMate really does have some fantastic XML indentation syntax highlighter, but will it really help get the project done any faster or better?

An urge to switch tools is often a signal to me that I'm bored or disappointed with my performance.
Try a non-work treat, like that new Flaming Lips cd you've been eyeing, or a few fresh strawberries

If the sun hasn't been out in a while, and it appears, go experience some sunshine. If the sun's out all the time, make some time to sit in the sun.
Sunblock is crucial; don't bring your laptop.

Reading academic research papers and textbooks require sustained, focused attention, which is impossible if you're within ten feet of your computer. Leave the laptop at home and get some work done for once.
Skim giant technical books so that you'll know where to look when you need particular information.
Don't try reading Unix Power Tools cover to cover, but do flip through it, or you might never know what sed can do.

If you're lucky, you work with people who are smarter than you, faster than you, write cleaner code, know more languages, have more experience, etc. Your tendency may be to compare yourself to them, and come off poorly in the comparison. Try this, instead: "Thank god I work with people who are smarter than me, because otherwise I'd be working with people who are stupider than me, and that would suck."
People who are literally geniuses are used to being geniuses. They probably don't think you're an idiot, because they're used to being smarter than everyone else.

Identify particular characteristics of your most effective teammates, and emulate that characteristic.
"Be like Pablo: refactor aggressively." "Be like Scott: keep the codebase tidy, but not obsessively so."

It is almost always a good idea to go for a little walk. (Thanks to Josh Carroll for this gem.)

Flickr in Open Laszlo

Working on the Open Laszlo LZPIX multiple runtimes demo made me fall in love with data-binding in lzx. LZPIX is a flickr browser written in Open Laszlo, which can be compiled as a DHTML app or a Flash app. To share the data-binding joy, I wrote a little flickr browser (requires Flash Player 7 or later) and annotated the application code.

rubyonrails.org has a really cool screencast showing how they built a flickr viewer in five minutes with, of course, Ruby on Rails. That screencast inspired me to get a Rails environment set up on my mac, so I'm following suit with a similar Open Laszlo app in the hopes that I'll inspire more developers to give Open Laszlo a test run. I'm not trying to argue that Ruby on Rails is better or worse than Open Laszlo. Consider this article as "imitation as flattery" not "competitive analysis."

Open Laszlo is a great platform for mashups. (marketing-speak: Open Laszlo is a great platform for building rich internet applications using third-party REST web services.) OL has data binding and replication built in. The results of an xml query (a "dataset" in OL) can be mapped directly to elements in the OL scene graph (the "canvas" in OL). Attributes of elements in the OL scene graph can be mapped from attributes of the elements in the dataset. The data replication manager creates views to represent each result of a query to a REST api.

I've used a simple wrapper for the flickr api, written by Elliot Winard. For this article, I'll write from the perspective of an application developer using this existing api. libflickr defines a class, photo, which is a thumbnail view of an image in a result from a flickr query.

OL is tag-based and requires well-formed XML, so I start off my lzx document with a single root element, canvas, and include the flickr library:
<canvas title="Flickr on Open Laszlo">
<include href="incubator/libflickr.lzx" />

To access flickr, we need an api key. I define a global attribute with the value of my api key. Get your own from flickr
<attribute name="myapikey" value="xxxx_GET_YOUR_OWN_xxxx" type="string"/>

At first I just want to view some flickr data without worrying about how I got it, so I'll just use this little stub that kicks off a simple query when the canvas initializes. I call the method "getRecent" on the gFlickr node, which is global. I pass in my api key as an argument to the request.
<method event="oninit">
gFlickr.getRecent(canvas.myapikey);
</method>

Add a view for the search results, containing its own layout:

<view name="results"
x="10"
width="${parent.height-20}" >
<!-- The wrapping layout arranges the search results in a grid, and
starts a new row ("wraps" the contents) when the contents fill each row.
This gives grid-like behavior without scaling the subviews.
-->
<wrappinglayout axis="x" spacing="5" />

<!-- Data binding is so cool. This element says, "make an instance
of class coolphoto for the first ten nodes in the dataset "photods" with
"rsp" as grandparent and "photos" as parent.
-->
<photo datapath="photods:/rsp/photos/photo[1-24]" />
</view>

That's all it takes. The app now displays see a grid of photos recently added to flickr. (Here's the code so far)

Now let's enhance it. I want some more interesting searches, so I'll add a few buttons to control the search:
<view
x="10">
<!-- Within this view, put the subviews in a row. -->
<simplelayout axis="x" spacing="5" />

<!-- Label the search field -->
<text y="5">Search Flickr:</text>
<edittext name="tagQuery" text="lzpix">
<method event="onkeyup" args="kc">
if (kc == 13) gFlickr.searchWithTags(this.getValue(), canvas.myapikey);
</method>
</edittext>

<button onclick="gFlickr.searchWithTags(parent.tagQuery.getValue(), canvas.myapikey)">
go
</button>
<button onclick="gFlickr.getRecent(canvas.myapikey)">recent</button>
<button onclick="gFlickr.getInteresting(canvas.myapikey)">interesting</button>
</view>


I want to show a larger image when I click on a thumbnail, so I'll create a view for the larger image:
<view id="gPhotoDetails"
x="10" y="${parent.results.y + parent.results.height + 10}">
</view>

Nothing goes in that view yet, though, so I'll subclass the photo class, yielding the coolphoto class, and add an onclick handler. In the onclick handler, I'll set the source of the details view to the url to the medium sized image.

<handler name="onclick">
var s = this.getImageURL("_m");
gPhotoDetails.largeview.setSource( s );
</handler>

Now the app now has some search ui, and shows a larger image when you click on a thumbnail.(Here's the code so far)
Let's add some tasty effects. I'll add an animator to the coolphoto class, which fades in the photo from transparent to fully opaque.

<!-- This animator fades the image in by animating its opacity. -->
<animator name="appear_animator"
attribute="opacity"
to="1"
start="false"
duration="800"/>

We want that animator to start as soon as we've got the data for this photo, so we add an init handler:

<handler name="ondata" args="d">
<![CDATA[
// Start the fade-in animation
appear_animator.doStart();
]]></handler>

I want to show some information about the thumbnails when I mouse over them. I'll create a tiny view called gFloater to float in front of the photos, and animate the floater to just below the photo being mouse-over'd. To get the photos title and owner, I just run an XPath query on my data.

<view id="gFloater" width="160" bgcolor="#333333" 
options="ignorelayout"
x="1000"> <!-- start off offscreen -->
<simplelayout axis="y" spacing="1" />
<text name="titlelabel" fgcolor="white" width="150">title</text>
<text name="ownerlabel" fgcolor="white" width="150">owner</text>
</view>
<method event="onmouseover">
gFloater.animate("x", this.x + 10, 500);
gFloater.animate("y", this.y + parent.y + this.height - 10, 500);
gFloater.titlelabel.setText( "t: " + this.datapath.xpathQuery('@title'));
gFloater.ownerlabel.setText( "o: " + this.datapath.xpathQuery('@ownername'));
</method>

the complete code and the finished application.

podcasts: good as a media delivery mechanism, bad as a standalone media

Diggnation and This Week in Tech are moderately entertaining but not more so than the standard friday afternoon gather around somebody's computer and show off some cool stuff. The guys of Diggnation and TWiT don't seem to have any special information to tell me; I maybe get a nice "in the know" glow from hearing similiar tidbits of useless information emerge in a disconnected context. (Can it be a context if it's disconnected?) Patrick Norton and John Dvorak and Leo Laporte each have interesting personalities, but I think they're interesting like, if this guy is sitting in the break room, i'd be willing to sit down and hear about what he's up to, but I wouldn't sit in rapt attention while he goofs off with a few other moderately entertaining curmudgeons. Podcast qua Podcast: no.
But! Podcast as a way to deliver actual valuable news and entertainment and analysis -- that's just right. I use my ipod (thank you, Marshall, so much) as a time shifter. NPR and BBC and Jim Lehrer and Weekend America and Slate all deliver bits to my device, and I just keep a casual queue going, with some smart filters. Most days I have a few hours of NPR content available, and a few audiobooks I get through slowly... The content is what's important. A bunch of guys chatting about tech, or, worse, just one guy talking about tech: blech. But if you've got some actual journalists composing stories and pieces and reporting on the news, and you make that content available to me to put in my pocket and listen to anytime -- now you've got my attention. Which is the new new new economy.

"It's the FED, you idiot!"

George W. Bush cannot summon the words "the Fed" when asked in a press conference what he thinks about rising interest rates. Check this out:
Q: For the first time in years, interest rates are rising in the U.S., Europe and Japan at the same time. Is this a concern for you? And how much strain are higher interest rates placing on consumers and companies?
THE PRESIDENT: First of all, interest rates are set by an independent organization, which --
Q -- still, are you concerned about that?
THE PRESIDENT: Well, I'm not quite through with my answer yet.
Q I'm sorry.
THE PRESIDENT: I'm kind of stalling for time here. (Laughter.) Interest rates are set by the independent organization. I can only tell you that the economy of the United States looks very strong.
from whitehouse.gov's transcript of today's press conference
It's the FED, you idiot! The Federal Reserve Board. Remember, you just appointed Ben Bernanke to be the Chairman of the Fed six weeks ago? Arrrrg. It's hopeless. Can we impeach him for gross incompetence?

making my slow mac fast

My 867 Mhz, 512 mb ram 15" titanium powerbook g4 is not slow. The key to getting this four year old to perform is to understand and take advantage of OS X's virtual memory structure. (Oversimplifications follow, but they get the job done; my mac feels fast.)
Virtual memory is on disk; physical memory is on chips. Chips are faster than disk. To run, an application must be in physical memory. When switching applications, the new application must be "swapped in" to physical memory. If that physical memory was in use by another application, that application must be "swapped out." A standard mac-ish application takes about 100 mb of memory. Switching between a paged-in application and a paged-out application involves writing ~100 mb to disk, and reading another 100 mb from disk. 200 mb of disk access takes a non-trivial amount of time... enough to explain that annoying pause when I hit cmd-tab or click on another icon in the dock.
Running fewer applications requires less application switching, so it feels faster. This brings me to my key insight for the day: For improved performance on low-memory systems, use web apps in the browser to replace traditional desktop apps. Firefox is faster at switching between windows and tabs (all resident in physical memory, presumably) than OS X is at swapping applications between physical and virtual memory. Did someone say "the network is the computer"?
This approach is great for the things that I need to do with a portable machine: coding (editing text files on the server, using Transmit and BBEedit), email (although Mail.app can be rather slow on big mailboxes; I should probably switch to Laszlo Mail soon), and web browsing. Photoshop, no way; I don't even have photoshop installed on this machine. Nor do I run tomcat or an Open Laszlo server on this machine. I offload those jobs to the right machines, which I have access to because my employer understands: a blazing dual-opteron linux server for tomcat and OLS, and a bomber dual-2 G5 tower at work.
Diagnosing where my memory is going is possible using top, and easy using Activity Monitor or iPulse. I learned that Adium uses an astonishing amount of memory, as do dashboard clients. This mac is going to be my portable machine for a long time yet, so, goodbye Adium, goodbye cute dashboard widgets... Hello, terminal, my old friend!

kitty-based ergonomic problems

I'm having a problem with my work-at-home ergonomics. It's getting worse since the IT guys installed a superhot server for me to use from anywhere (so long as I do two hops of ssh tunnels for four ports) so I can do more real work from home, faster. The problem is the kitty. Darling has an oral fixation. She insists on licking my thumb or finger constantly, for hours at a time, whenever I'm around. When I'm getting ready for bed, I have to leave a hand outside the covers or else she'll paw at my face until I give her a bit of finger to nibble on. Which is okay, because I'm sleeping. The problem is programming. My hands are an easy target, so Darling sits on my left wrist and nurses on my right thumb. Sometimes she doesn't do the oral-fixation thing, she just sits across both of my wrists. Darling weighs 16 pounds. If I push her away she nudges around until she can sit down in the same place again. This is an ergonomic problem. I'm pretty sure a sixteen pound weight on my wrists while typing is not ideal. Also it makes it hard to reach for the keypad and the mouse. On the other hand, she keeps my wrists warm.
I'm going to try putting catnip on the easy chair.

I love my manager

I asked Sarah for a "management interlude" this morning, to help me set priorities for today. We got on the phone and the first thing she said was, "You don't have to work today, you know." That is so non-Web1.0 I love it. Because, of course, I want to work today. I told her, "Well, maybe I'll take more naps than usual, or work more in pajamas than usual." We agreed that was a good idea. Sarah has also said, she works the first eight hours a day on what's most important to Laszlo, then after that, on what she wants to do. This is perhaps the 50-hours-a-week version of the 20% project. I could do with a few fewer projects though. Side projects reproduce like bunnies who mate with other people's ideas. Current side projects:

  • secret cool thing to improve laszlomail usability

  • book chapter on visual effects for laszlo

  • laszlo viewer for delicious library

  • learn cocoa programming

perfect sunday morning: coffee

This has been a perfect sunday morning. My co-worker Bruce and his wife Kira gave me a french press they hadn't been using, and I bought a quarter-pound of Mocha Java yesterday, and half-and-half, and sugar... and I woke up and made myself a perfect cup of coffee at home, for the first time ever. The french press actually let a bunch of the grounds through the screen, so I filtered it again through a paper towel. Who needs coffee filters when we've got Bounty?
But it gets better: I took my mug of coffee and got back into bed. Can you beat that? Is that beatable? Oh. Yeah... if I had a sweetie waiting for me in bed to drink coffee and cuddle and help with the crossword puzzle.
Thus my work towards rebuilding my social life! In the last week I've gotten together with friends three separate times! Four, even, two days with one person. Amazing, absolutely amazing. And now I'm going in to work for social-thing number five, helping a co-worker get started with programming while I put my book chapter together.
Good lord, it's a good day.
If you were wondering, my dreams were of the epic-fantasy variety, strongy influenced by A Feast for Crows by George R. R. Martin.

tool of the week: colorzilla

Colorzilla, an extension for Firefox (including 1.5), is my favorite tool this week. I just discovered it twenty minutes ago. (Make sense of that, I dare you!)

Install it, restart firefox, then notice the little eyedropper icon in the bottom left corner of the browser window. Control-click on that icon; you get a menu. First go to "Options" and select "Auto Copy: Enabled." Choose your favorite color format from the Auto Copy menu; I like "#FFFFFF".

To sample a color: hit shift-escape, the default eyedropper invocation tool. The cursor changes to a cross. As you move the cursor around the screen, the status bar at the bottom of the window displays configurable information including the hex code of the color you're over. When you're over a color you like, either click on it, or hit shift-escape again.

NOW THE JOY: Go to a text editor and use your favorite keyboard shortcut for paste, command-v, let's say. THE HEX COLOR OF THE PIXEL YOU SAMPLED IS PASTED INTO YOUR TEXT EDITOR.

It gets better. Hit shift-escape to go into yedropper mode. Then hold down shift and click on a color you like. You're still in eyedropper mode! Shift-click on another color, and another. All of the colors you sample are accumulated in the history color palette. Ctrl-click on the eyedropper icon to get the ColorZilla menu; select Color Picker, then go to the Palettes tab. Select History from the drop down. AMAZING: this is a palette of the history of all the colors you've sampled.

One more thing: it works in Flash.

It's not as mac-ish or sexy as xScope but the auto-copy-hex-of-sampled-pixel might be enough to switch me from xscope.

It's a good day for backups.

You've got the day off, you're sitting around having a mellow afternoon, and you're about to launch a new year's worth of work. Now is a great time to make some backups. If you don't have a formal backup program, and you're within the sound of my voice, I beg you: make today the day.
If you've got a mac, join .mac, and use their Backup 3 software along with their iDisk, with monthly burns to cd or dvd. This costs $99 for a year, plus an hour a month feeding blank disks to your machine. Your mac will tell you when it's time to back up.
If you've got a PC, I don't know what the industry standard is; probably something from Symantec? Pay money for the software (should be about $100 I think) and then use it at least once a month to back up to hard media.
Then go one step more: bring a complete backup set to a different location. If you've got a safety deposit box, great; a drawer in your desk at work is also fine. Or ask a friend who lives in a different zip code to tuck your backups into their files. Why? Floods, hurricanes, fires, burglary, psycho roommate: many things that destroy your computer can also destroy a set of backup cd's stored in the same location. Life will be hard enough if the levees break; at least your data can be safe if you do some regular preventive backups.

triumph!

Who says I'm just a client-side kid? Check out what I just learned about compiling OpenLaszlo on our brand new 64-bit linux server:
jikes 1.22 was already installed in /usr/bin/jikes, so I just had to change build-tools/build-opt.xml to have build.compile.path to /usr/bin/jikes.