But now I've discovered a way to read my ebooks that makes the experience tolerable.
My friend Jeff has been preaching the gospel of paperless books to me for almost a decade, but I've resisted for a long time. Now that I live in a place where it takes a few hours to just get to Borders and search for a tech book, I've started to cave. When I need a new tech book, I buy only the e-book. It's environmentally better, since all of the info will be outdated in six months anyway. Besides, it's not like I want to have a study full of classic web application books. Buying paperless books means I'm doing my reading mostly in Apple's Preview application.
The Bug Happy Fun Thing I found that has made reading tolerable in Preview is the Note Annotation tool.
It lets me make little notes of my thoughts as I read something. With tech books, this is great, because there are a million and one things that I read but then forget, or can't find again without searching for 20 minutes. Now, if I see something in a book I want to blog about later, or use in a project, I just add a note. When I'm ready to use whatever interesting page in the ebook that I've "Note'd", then I just view all Notes in the sidebar. No searching.
It's all about the little things.
Dave pointed me to the announcement about IE8's standards mode this morning. The short of it is that the IE team will do The Right Thing with version 8, rendering in IE8 standards mode by default, not IE7 standards mode, which can still be explicitly requested via meta tags. See the A List Apart article for how to do that.
I have two questions. First, why did anyone ever think it was a good idea to make IE7 Standards mode the default in IE8? I know all of the technical reasons and backwards compatibility blah blah blah, but when is a new version allowed to be a new damned version already? Second, why do they have Peter Boyle from Young Frankenstein at the podium on their Interoperability Page? I know I can't be the first to draw that comparison, but the resemblance seems particularly striking in this shot. Oh, and third, why is the name of that image file "hero.jpg"?
The Netflix Watch Instantly feature is pretty cool. There are a bunch of interesting documentaries, some good foreign films, and loads of kids shows on there (including Doggy Poo). Since we have decided to see how long we can hold out before paying for cable or satellite TV, I thought I'd ease the pain a bit by rigging up a Watch Instantly setup for our TV. Here's how I did it.
First, I already had an old PC with a Radeon 7000 in it. So I had RCA video out. I also had a sound card. I needed the two cables: one RCA video cable to go from the video card to the VCR or TV, and the sound card-to-RCA splitter cable. This has a headphone-like plug on one end (for the sound card) and the red-white RCA cables for left and right audio on the other end. I plugged these from the computer into the VCR, because it was more accessible.
Next, I had to get network to this box. I was so tired of wireless dropping out when the neighbor microwaved their popcorn or whatever that I actually wired Cat5 to my entertainment center. Once that was working, I verified I could play the netflix movies on the TV. I set my resolution down to 800x600 to be truer to the TV's 648x486 or whatever it is. If I had a decent TV, I could have left it at a more readable resolution I'm sure.
The final step was finding some way to control the PC so that I could browse movies and select the one I wanted to play. Reading text on the TV was extremely difficult, so I wanted a better screen.
I realized that since Elly always has her laptop going, I could just set up VNC between that and the TV's PC. The laptop would be a really big, but versatile, remote control. So that's what I did. RealVNC on the PC and Chicken of the VNC on the laptop. It works like a charm:
It's tricky learning design, especially as a developer. And I'm not talking about the aesthetic stuff--for some developers that may be downright impossible--I mean the technical world of HTML and CSS. The problem I've had over the years is that, as a developer, most CSS/HTML information on the web is not targeted at someone with my background. If you're like me, then you have a BS degree in computer science or engineering from a university where you were made to sit and think about everything from processor pipelines to XOR gates to compiler optimization to how much wood could a wood chuck chuck if a wood chuck could chuck wood and what would be the complexity of said wood-chucking in big-O notation, thank you very much, here is your degree, now go learn Java or Xt or MFC or whatever in the real world on your own.
So you know enough to write the CSS parser and rendering engine, at least on a theoretical level. But that won't help you to use it. Nor will it help you to know the quirks of the several rendering engines out there in the real world.
So I find myself in this quandary of knowing too much for my own good when I sit down to learn about CSS/HTML. Then I get impatient. I want the articles targeted at design-people to just cut to the chase. Stop talking about "If you wanted to have these pretty flowers in the upper left corner, you would float DIV x and put a background..." Show me the money. I'm not an art major. My web pages may suffer for that, but I can understand the box model if you would just tell it to me already.
The purpose of me writing this post, then, is to collect a few choice resources I've discovered in my own haphazard and unofficial CSS/HTML career.
Find a good CSS reset to start from ground zero. My philosophy is to know as little as I need to about the difference between browsers. The less you fill your brain with that meaningless crap, the more room you have up there for knowledge that might actually enrich your existence. One way to cut down on the browser-difference arcana in your head is by never using the default styles, which vary from browser to browser. You can choose from many of the reset CSS recipes out there:
Don't using clearing elements. I used break tags (BR) with a style of "clear: both;" for a long time to clear floats. Even though it is the W3C-recommended approach, clearing floats in this way will drive you crazy. (It is difficult, if not impossible, to get those clearing elements to share a uniform height across browsers.) I use Tony Aslett's clearfix method personally, although Dave pointed this out to me. It is a more recent technique, but I'm a bit hesitant to start using overflow to achieve clearing. It gives me scrollbar nightmares.
Understand the Holly Hack. I never understood the difference between clearing floats in IE and other browers until a I read an explanation about why the Holly Hack fixes it. I wish I had read this years ago.
Use Chris Pederick's Web Developer Toolbar. This is the single most awesome CSS tool that I use. The Edit CSS and View Style Information tools are almost all I need. Occasionally I will drop into Firebug when the View Style Information tool doesn't do the trick (it doesn't show the inherited styles as well as Firebug).
Don't take on IE6 without CSSVista. If you're like most people, you develop everything in Firefox or Safari first, then drop into the depths of hell to work out whatever is broken on IE6. One nice tool that lets you interactively edit CSS in IE and FF at the same time is CSSVista. It's free. It's not perfect, but it's the best I've seen for IE yet. The IE Developer Toolbar is also nice to have.
Don't buy reference books. It's funny how many CSS reference books there are. Same with HTML. You don't need me to tell you that these are a waste of paper, including that green paper that is your money. But there are some good CSS books that discuss layout techniques and browser bugs. It is definitely worth having one of these. I like this one a lot. It is also good to have a CSS cookbook on hand when you need to remember the right way to do some common CSS task. I use the CSS Anthology from time to time.
Read this book. For all of us who are not graphic design majors, who didn't know all those fancy terms in that documentary on Helvetica, I recommend The Non-Designer's Design Book. Nothing has helped me more in grasping the basic aesthetic principles of laying out a page. If you have to do anything with design, even if it's just laying out your church bulletin, you should read this book. It's short, easy, and will have you making passable designs in one day.
If you are a dev who has been designing for a while, this is probably all old hat to you. But if you're like I was a couple years ago (clueless), then an hour spent reading the links above will hopefully be a great starting point for you.
I just got forwarded an article by Hank Williams from a client who has been watching the ongoing Twitter scalability rumpus that has kept us entertained for literally years now. Blaine's recent point about scalability is one I would mostly agree with, and one which I'm sure he's tired of making. I haven't really been following the Twitter-talk on all of the techie blogs, except through hearsay. "Did you hear that TechCrunch said Twitter is dumping Rails?" "Did you see that post about Twitter scaling?" Yada yada yada. Half of it is inaccurate the moment it is posted, and the other half is fraught with misunderstanding and wild speculation.
One of the reasons I've been loath to follow these discussions is underlined by William's concession at the end of his post that, indeed, Twitter's scaling challenge is a "hard ... problem that requires a very specialized ... architecture." Aren't they all? And so that is why I don't read the pseudo-tech jibba-jabba of TechCrunch and others about the scalability of Rails in general based on the experience of one very unique site. Scalability is unique to each site. Indeed, you are a unique site when you have to worry about scalability. That means you are getting lots of traffic, and probably making money. Most sites don't make it that far.
But I didn't write this post to join the Rails scalability rant. I just wanted to mention one observation that I haven't heard yet in the Rails scalability discussion. Here it is: the web is a moving target, and the current discussion often fails to acknowledge that. The web today is demanding more of frameworks, languages, developers, and system architectures. For instance, on MOG, we knew scaling would be a major problem from the get-go because a central piece of the application involved hundreds of thousands of agents running on users' disks, reporting tens of thousands of songs. What website was doing that in 1997? For what piece of software are those numbers not a scalability issue? It's the same with Twitter (as Hank points out): millions of people tweeting all at once, very frequently, via web, phone, Facebook apps--who knows, maybe there's even a Twitter client for your hair dryer or coffee maker now. This sort of challenge is (relatively) new for the web. And new ones like it are being invented every day. The target is constantly moving and changing shape.
If we nailed down the goalposts of web scalability, no one would bother posting and trolling and debating about Rails scalability. It would be solved by a handful of good engineers in a couple of weeks. For good. But what would be the fun in that? You'd never hear about another site that does something you wouldn't think possible 5 years ago. And, as an engineer, you'd never have the fun of solving new scalability challenges to support those new sites.
So far, I am really loving the Garmin Communicator Plugin. It is one of the best applications of a browser plugin that I have ever encountered. I suppose any browser plugin that allows you to pretend your browser is a desktop application is a great browser plugin. That's what I like best about the Garmin Communicator, anyway. You can plug your Garmin device in via USB, then sit back and let some free web application do its thing with your data. No download-upload nonsense.
Here's a little sample of how I'm using it in WalkingBoss (not live yet):
Things have finally calmed down a bit here. We're moved in to our new home, my office is set up, and I'm no longer looking for rogue printers to smash.
What's new? Well, I bought a house, got a dog, and moved. All pretty much within a month or two of elapsed time. I feel about 20 years older after doing all of that, but the calendar tells me that I've really only lost two months. Plus however much time you lose from eating 30 Filet-o-Fish sandwiches in as many days due to not having any of your kitchen stuff to cook with. Probably shaved about six months off my life there.
I've been on Facebook a bit lately, mostly for work. I don't really like Facebook, but on the plus side I've located a bunch of old friends. It's a bit weird how the internet enables you to keep track of your friends without really having to keep in touch with them. I mean, there's the usual "Hey, you're still alive, that's great!" conversation that seems part of the "friending" ritual. But beyond that, Facebook seems to be just a glorified address book for me. I know my friend Dave sees a lot of potential in Facebook, so I haven't completely ruled it out as another fad yet. But it will be a while before I'm really sold on it, as a user. As a technical person, of course I see the huge advantages it provides as an application delivery platform. As a regular person, I don't know if I'd still be a Facebook user if my job did not require it.
Our new dog is proving to be a great addition to the family. We found her at the animal shelter in Belgrade a week after we moved here. She is a Karelian Bear Dog, a breed with which I have been enamored since first reading about how they are being used to help with problem bears at the Wind River Bear Institute. When Elly looked on PetFinder and saw that a KBD was available, it seemed like a sign from above. We had both been joking prior to moving up here that I could own my very own bear dog, but I don't think either of us thought that it would happen so fast. For one, they're supposed to be super active and need some land to roam. Our tiny backyard would seem small to a Pomeranian, so I wasn't planning on getting a bear dog until we moved to a place with more acreage. But luckily for us, Sadie is an older dog who would rather lay around and squeak out dog farts all day in exchange for some chicken jerky treats. She's still a great dog, and she will play with you if you pretend to be a big vicious animal, but she is by no means chewing off our doorknobs or running off into the hills. In fact, just this morning she made me walk at about negative 1.5 mph up a hill back to our house in a windy snow squall because she was tired after our morning jaunt.
On the technical side, I'm continuing work on TravelersTable, while in my spare time trying to resuscitate WalkingBoss and develop a time-tracking module for the IDE I use (NetBeans). I've found that all of the dog-walking I'm doing has been good for my creative-technical side. The ideas come a lot easier when you're not stuck behind the LCD all day long. I'm considering getting back into ObjC or OCaml once I'm done with my other projects. I got an OCaml book for Christmas a year or two ago, and I never made it past the first chapter. Plus I've got some ideas about a WebKit app I want to build in ObjC. Too many ideas, too little time.
I guess today is tax day, as two people have already reminded me in their emails. I had forgotten because my taxes were done a bit earlier this year. The deadline for corporate returns is a month early, so I got all my stuff together for the accountant back in March. I'm pretty excited. I think this is the first year I will get a refund in about three years. It's not too much, but just knowing that the government won't take a big bite out of my hiney this month is a great feeling. For a couple years there, it seemed like any savings I built up were gone after April 15.
Speaking of money, I am totally amazed at the difference between Whole Foods and the local Town & Country supermarket here. I swear we pay 30% of what we did in Boulder. I do not understand cost of living at all. Dave told me he paid $13/lb for turkey at a Whole Foods in California while he was visiting family. Thirteen bucks for a pound. I think here it's like $4/lb or something. Of course, the comparison is a little skewed--I mean, it's not just cost of living differences when you compare a regular supermarket and Whole Foods. The Whole Foods turkey most likely spent part of its young life reading Plato, playing frisbee, and talking about social issues late into the night over some kind bud at a $40,000/year liberal arts college, so that figures into the $13/lb. But still. That's a huge difference.
5. Since you have no legs and are therefore not ambulatory, you can not get away if I decide to teach you a lesson.
4. I'm paranoid. After two consecutive paper jams I start to think you're just playing with me.
3. Underneath that gray plastic shell you have breakable parts, like...your scanner glass.
2. You are replaceable.
1. My Kung Fu Heel Hammer Kick.

I lost it today. I thought I'd give a little warning kick to this piece of crap when it jammed on me for the 8,023,235th time. I guess I kicked a little too hard because I heard the internals rattling around after my first kick and that set me off. Once I knew I had broken it, I got a little crazy and just kept kicking it. I guess movies really do inspire violence.
Elly and Tova came home just as I was vacuuming up the evidence. Elly asked, "What happened in here? Did you kill somebody?"
"Yeah, I did. I killed a printer today."
This is one of those short articles that I post only when Google fails to turn up any useful information and I hope my solution will be helpful to others. If you are using the acts_as_taggable plugin in an older Rails project that you've recently come back to upgrade to Rails 2, you may find that you get an error like this one: NameError (undefined local variable or method `acts_as_taggable' for ...
I honestly don't know what changed, possibly the updates that were made to auto-loading constants (which I never really bothered to learn about), or maybe the difference is in my rubygems version. I'm not sure. Anyway, if you're seeing it, you can try putting this below your gem statement: require 'taggable'.
That fixed it for me, using Rails 2.0.2 and the acts_as_taggable gem version 2.0.2.
I have been afraid of admitting that I miss my IntelliJ for a long time now. I'm coming out of the closet today. I know some people will think of me differently now, possibly shunning me in favor of people who think vim + screen = bliss. I'm willing to take that risk. You see, I've found NetBeans with the jVi plugin, and I'm happy again.
Ok, weird coming-out jokes aside, I must say that I've been meaning to write about this for a long time. But I could not find an IDE I liked, and I could not bring myself to write a post about how there are no good Rails IDEs and I hate my life because of it. How dark. Only Satan-worshipping Finnish-metal-band-listening grandma's-basement programmers would have found any joy in reading that crap.
So I postponed writing about it until today. A happy day. Because I have found NetBeans.
Why do I like NetBeans? Well, first let me tell you a little about my long journey through the valley of the shadow of IDE.
I started out with Komodo because I like ActiveState (as a former TCL/Tk person, I will always appreciate their work on that language). I was impressed. For a cross-platform IDE, it was probably the fastest I had encountered on Mac when I tried it (probably about six months ago). But at that point, debugging was too slow. It took me over five minutes to start up webrick or mongrel and reach one breakpoint. Sorry ActiveState, I was using a G4 PowerBook. Debugging would probably be much faster on my MacbookPro. I appreciated the built-in VI keystroke emulation, but I found it lacking in some small ways that nevertheless irked me.
Next I tried RadRails, which had become the Aptana Studio or something like that by the time I got around to trying it. After downloading and installing it, I gave it about five minutes of a chance before moving on. If I recall correctly, the VI integration was a shareware (i.e. not free) plugin, and the Rails support felt too much like a simple Eclipse plugin rather than a core part of the IDE. I think if I had been an Eclipse user originally (as opposed to an IntelliJ user), I might have been ok with RadRails.
Next came Borland's chance: 3rdRail. I really got excited about this for a few minutes. Actually, it was a few hours. But then things broke. There were lockups and the occasional crash, and some of the navigation features seemed to have kinks that were not yet worked out. Granted, I was using one of the very first trial releases, but I sure was not going to make the $400 bet on a license that they would fix these bugs quickly enough for me.
I moved on to my favorite ol' mule of days gone by. IntelliJ: the pride of Czech Republic. I had read about their Ruby plugin a while back and thought it might be nice to try. The IDEAVim plugin had served me nicely in the past, so I knew I could have my VI keybindings easily enough. However, when I tried to install the Ruby plugin, I needed a newer version. The newer version ran slowly on my MacBook Pro, and it was going to cost me an upgrade fee to use it once the trial ran out. I tried the Ruby plugin anyway (with the trial version), and it worked all right. I was able to run my code in IntelliJ, although I didn't get around to debugging it. My main objection was that the plugin felt too much like a plugin. I couldn't forget that I was using a Java IDE to write Ruby code. Besides, I didn't want to spend the $100+ to upgrade to the newer version when it seemed like just yesterday I had spent $250 for a professional license.
I gave up for a while after trying all of these. I resigned myself to the possibility that I might always be debugging my Rails projects with "puts" and logger.error. Then my officemate mentioned a new NetBeans release. I was skeptical, but so brimming over with cynicism about Rails and TextMate that I gave it a try. I was desperate for something to come to my rescue.
I haven't looked back since. There were so many things I instantly loved about it:
- The error detection and suggestion saved me time immediately.
- The debugging actually worked and was quick!
- I could easily control the scope of Find In Project.
- Many of the shorcut keys were so similar to TextMate that I had them memorized before lunch.
- The jVi plugin worked well and had the most complete vim emulation of any I've encountered so far.
- The Subversion support was nearly perfect.
- The code completion and popup documentation were snappy and easy to use.
- Built-in plugin management and generator wizards meant less time typing commands in a console window.
There is certainly room for improvement: Java looks stupid on the Mac (I tried the substance plugin but found it uglier in most configurations); it is not as fast as a native app would be; the Go To File functionality could be quicker (and allow for spelling mistakes); it would be nice to be able to run script/console inside the IDE. But for now, the pros completely outweigh the cons. For something like my GPX gem, where unit tests are important and I have no "Shift-Reload" concept for seeing if something is working (as in Rails projects), it is proving to be indispensable.
I used to doubt that the browser was becoming the new desktop. I mainly used the GMail web interface for its portability, not its usability. That is, I liked being able to access my email from anywhere, and I didn't really notice a difference in ease of use between desktop clients and webmail. If anything, back then the webmail interfaces were a definite step down. Web apps were clearly still far from replacing desktop apps. But recently I decided to try a little experiment. The results have since overturned my skepticism.
I tried switching to Thunderbird a few weeks ago. Firefox was being its usual pig-slow self, and I had a lot of things going on, so I could no longer afford to wait 3 minutes to switch between tabs (I'm still on a PPC Mac). So I did it. I used a desktop email client again for the first time in about a year.
But now, after a few weeks of using only Thunderbird, I'm back on the browser. And not because my email was being scattered about on different machines. I switched back purely for usability reasons:
- Search was more accurate and faster in the GMail web interface.
- It seemed easier (believe it or not) to lose a draft in Thunderbird than in the GMail web interface with it's auto-save feature.
- Switching between rich text and plain text in the desktop client was next to impossible compared to the simplicity of the web client.
- Without the conversation grouping feature of the GMail web interface, I felt a lack of context. I had become so used to this Gmail feature that it was disorienting to read email without it.
- I had to sacrifice gigs of hard disk space after POP'ing my GMail inbox down into Thunderbird.
In fairness to Thunderbird, it is a great email client. If I had to use a desktop client, it's the one I'd use.
At this point, I should probably list some of my gripes about the GMail UI, but, oddly enough, I don't have any. I only have gripes about the GMail deilvery platform (aka, the web browser).
What I really want in my email client is stability. A stable email client should be immune from whatever crap may be running in other tabs in my web browser. A stable client should not give me the Mac beachball when I want to switch quickly between inboxes (browser tabs, in this case). So what I really want is a dedicated client program. A fast browser that contains only my GMail accounts. Something I can "Apple-TAB" directly into.
I googled for something like this today and found this simple WebKit-based browser. It is almost exactly what I'm looking for. The only thing I'd want to change is the ability to have multiple GMail accounts open in separate tabs. But the simplicity of a browser that is dedicated to email is surprisingly refreshing. In fact, I was so compelled by this concept, I even broke out my Cocoa/Objective-C book this afternoon and started playing with the source! (And I got absolutely nothing done, but I had fun re-learning Xcode.)
Most people who have their own small business end up giving a lot of their free (un-paid, that is) time to a task they were never formally trained to do: bookkeeping. Some people are naturally good at it and find it a nice change of scenery from their main business, others hate it with a passion. Personally, I fluctuate. One day I find myself leaving the office with a great sense of satisfaction, knowing that I just printed my own paychecks and closed out another month's worth of work in such a way that I won't be scrambling come tax time. Another morning might find me, smoke billowing out my ears, cursing a blue streak about an entire morning of work lost to bitch-slapping Quickbooks into submission (or QB bitch-slapping me, which is more often the case). Lately, the thing that's been making bookkeeping a real pain in the ass for me is the mundane, everyday task of keeping count of my hours.
When I switched to Quickbooks early this year for all of my bookkeeping, I also started doing invoices in Quickbooks. Previously, I had invoiced by hand, keeping count of my hours in a text file. To make invoice generation as simple as possible in QB, I also tried using the weekly timesheet feature. Over the last few months I've come to hate this feature.
To use it, I have to interrupt my workflow, go to another window, do a bunch of slowpoke clicking and key-poking.
That sort of interruption is costly for me, especially since, as a contractor, I try to keep track of my hours as exactly as possible. If I have to switch off a project for a five minute phone call, I don't want the client to pay for that. Seriously. I want to be able to take those five minute phone calls without having to spend another five minutes inside Quickbooks recording the fact that I stopped work for 5 minutes.
So today I wrote a little program that lets me keep my hours the way I like, in a text file, while making it very easy to do a monthly (or weekly or bi-monthly) invoice in QuickBooks.
Here's how it works.
- I keep a little text file in ~/.hours/hours.txt. It's format is something like this:
Monday 7/2 # Bug-fixing and feature X 9:04 - 11:37 # Destroyed bugs 217, 381, and 113 12:02 - 6:23 # Implemented the hell out of feature X Tuesday 7/3 # Unit tests 9:03 - 9:07 # Sent quick email 3:23 - 5:30 # Wrote some unit tests for feature Z
... and so onI like to invoice monthly, so make a new one of these every month, and archive old ones as I enter a month.
- Whenever I need to find out how much to invoice, or if I'm curious about
whether I've been slacking this month, I run my little hours calculator
program:
I can even give a rate to see how much money I've earned:
Before I took the morning off to write this little application, I did play around with the many time clock apps available. None of them ever really fit into my work flow, as a programmer. It sounds so silly, but I was always frustrated with having to leave my editor to record a new couple of minutes or hours of work performed.
With this text-based approach, I just keep a link to my current hours.txt
file in my project (whether it's in TextMate or IntelliJ or Vim). Then I just
tab over to that file, enter in a line and forget about it:
If you want to experiment with keeping your hours this way, again, here's the program. (If you find this useful, please drop me a line!)
Having a DRb ferret server is especially useful to me because, with TravelersTable.com, we have cron jobs that need to run off-line and update indexes. Before switching to ferret_server, I always ran into lock contention issues while updating a Ferret index outside of the main Rails app. We would have to kill our Rails app, make the index updates quickly (or at some time in the middle of the night when no one noticed), and then re-start the app. So far, using ferret_server, I've been able to update the index without disturbing the app, which is really very nice.
Finally, if you're going to make this switch, one thing to be aware of is a sorting bug. For the full explanation and a patch, see this post by Mike Mangino.
