Mac OS X 10.5.7 is Out on Software Update

May 13th, 2009

Leopard.jpg

Can't help but like this - a new version of Mac OS X is available on Software Update 10.5.7. From what I've heard, this looks to be one of the last updates to 10.5 before the release of Snow Leopard (10.6) later this year. There is a complete list of updates available, and a separate list of security fixes. Not bad.

Gotta take the time to update.

UPDATE: on the update, my machine hung and I had to power-cycle it. When I did that, everything resumed updating normally, and things worked themselves out. Also, after the update, I did another Software Update and got the latest Safari 4 Beta. Nice.

There’s Almost No Replacement for a Good Developer

May 12th, 2009

GeneralDev.jpg

I've been doing a lot of stuff today on a project another developer built. There are a lot of interesting ideas in the code, lots to use, but there are little things that keep making me wonder why it was put together the way it was, and that slows down what I need to do. An example is that the code throws a NullPointerException for an unknown command, and that's OK. It's the expected behavior. In my mind, there should never be a NullPointerException thrown because it's just too easy to check all the times you'd get one, and make sure that you don't try to message a null. Simple.

This made me think back to several conversations I've had in the past with developers, as well as lots of things I've read over the years about the productivity gap between decent developers and really top-notch developers.

There's clearly a difference between great developers and good developers. Much of it is experience, domain knowledge, and education. But it's not always that simple. Some of the best developers I've worked with did not have a wealth of experience, but they had made the most with the experience they had. They weren't the ones with the most education, but they kept learning and always drove to the root of each problem to make sure they understood why it happened, and what needed to be done to correct it. And I suppose in doing these things, they acquired the best experience in the time they had.

But how they got it, or what their specific qualifications were, aren't nearly as important as how they did the job. That's the big difference.

A great developer is worth far more than a good one. Even the development paradigms designed to make great developers from good ones don't really work that well. Sure, they will make fewer bugs, and the effective developer multiplier might be 1.5, but it's never going to be 10.0 - it's just not realistic. I think of woodworking... using bad, rough, chipped tools in different ways may make the table look better, but it's never going to be the same as using good tools, and the right tools for the job.

While in many cases, it might not seem like it matters, in my experience there are more times that it does matter that management doesn't think it does, than times that it really doesn't matter. Management fools itself into believing that it doesn't matter if this is throw-away code. But it does. Hacks hurt.

In the end, I haven't found the replacement for a really good developer. They understand the problem, how to design the right system - not too little and it can't expand and grow, and not too much so that it's overly complicated for the task at hand. It's a skill. It's not magic or luck. And those that think it doesn't matter are kidding themselves. It does. All the time.

Creating Server Admin Tools in AJAX

May 11th, 2009

AJAX.jpg

I have to say that while it's been tedious to do some of the servlet functions for the server administration, it was amazingly easy to do the communication and GUI. I mean this is really the strength of the "Web 2.0" (AJAX/CSS) way of doing things. Had I known of this back in my last job, I'd have never built the monolithic old-style web app that we built. Everything was a call to the server and a new page. The calls could have been so much more lightweight and the interactivity so much better.

Even the Java applets could have been nicer as they could have done similar things to get the data from servlets and update themselves automatically. Simple.

But, in fairness, that project was started at least three years ago, and while the technology existed, there wasn't the level of support and understanding there is today. Well... at least that's the story I'm going with.

It is nice to be able to whip something up quickly and have it work very nicely.

Multi-Threaded JavaScript – Not What You’d Wish For Exactly

May 11th, 2009

SquirrelFish.jpg

I ran into a bug in my web app today that I should have seen coming, but my head hadn't been in the multi-threaded space at the time, so I missed it. The core concept is that JavaScript can be driven on multiple threads (timer, user interaction, callback, etc.) and if there are multiple threads doing things to the same codebase, you have a multi-threaded program, and you'd like all the tools a general multi-threaded language.

In my reading, I have heard that certain JavaScript engine implementations are single-threaded, but that's not part of the specification, and it's up to the implementors to decide whether or not to make the engine multi-core. In general, I think it's more likely that as time goes on, more engines will be multi-threaded rather than less.

The code I was having problems with this morning looked like this:

  prevRange = graph.getVisibleChartRange();
  if ((prevRange.start.getTime() == maxGraphRange.start.getTime()) &&
      (prevRange.end.getTime() == maxGraphRange.end.getTime()))) {
    prevRange = null;
  }

where I'm getting the selected range on the Google Visualization AnnotatedTimeLine widget and comparing that to the original (un-zoomed) values, and if they are the same, I'm nulling it out. The reason for this is to preserve the zoom level across changes to the graph, but the problem is very tricky.

Since JavaScript is inherently multi-threaded, I have to be aware of the possibility that things are being changed underneath you from timers and AJAX requests... so there's the possibility that while you're running this code, the graph itself is updated with data and redrawn, and in that redrawing, the data is invalid, and there will be no valid range on the graph. Resulting in the first line returning null.

This null then creates a null pointer exception in the code when it's asked for start in the second line. Not nice. So I had to protect the code from that possibility by saying:

  prevRange = graph.getVisibleChartRange();
  if ((prevRange != null) &&
      (prevRange.start.getTime() == maxGraphRange.start.getTime()) &&
      (prevRange.end.getTime() == maxGraphRange.end.getTime()))) {
    prevRange = null;
  }

The problem with this is that it's possible that there was a zoomed range, and in the redraw, and just plain bad timing, we're going to loose that because the method getVisibleChartRange() is going to return null when it was just incapable of returning anything meaningful. The better solution would be to have a mutex on the graph, and have it not return anything while it's redrawing, and then when it's done, return the answer.

But that would presume the concept of a JavaScript mutex. But nothing like it exists. Odd, isn't it? It just hit me this morning, and I did a bit of Googling to see if there were anything I was missing in JavaScript or a library that might act as a mutex, but there really isn't. That's too bad. Really too bad.

What it means is that there's going to be something like it one day, and that's going to make coding in JavaScript much nicer, and it also means that there's nothing I can really do to fix up the code. There is a slim possibility that there will be an update to the graph while hitting that one section of code that will be invalidated by the inability to lock (block) the update.

I suppose I could think about setting a value before the update and then restoring it afterwards... Hmmm... something to think about.

MarsEdit 2.3.2 is Out

May 8th, 2009

MarsEditIcon128.jpg

I just got a tweet about an update to MarsEdit to 2.3.2. The Sparkle notes say that the changes include:

  • Flickr browser fixes
    • Add support for deauthorizing the current account
    • Fix an issue where a bad URL or missing image size could be inserted
    • Fix a bug in the display of ampersands (&) in image titles
  • Use Leopard 10.5 style for window's status bar text
  • AppleScript date-setting command now accepts string date descriptions

and while I don't use flickr a lot, I do have some pictures there, and with the iPhoto integration, when I get a camera I will carry, it might be a nice way to put images on the weblog.

Definitely worth the upgrade time.

Google Releases Chrome Update 1.0.154.65

May 8th, 2009

GoogleChrome.jpg

The story seems to be that there have been two recent updates (as in this week) to Google's Chrome browser - one for a security fix, and another for a problem with the 2D image handling. At the same time, I got a call yesterday from some network security folks asking if there was a way to run my web app in the Chrome 'environment' without allowing the users to run the browser itself.

I understand their position - network security is such that an unknown must be considered dangerous, and certifying something is going to take a lot of time and effort. Unfortunately, the JavaScript in the Google Visualization API needs something like Chrome to work well at the amount of data that I'm working with.

So there have been a few updates this week. Nothing major for me, but certainly something to keep an eye on from the network security folks.

Dropbox 0.6.513 is Out

May 8th, 2009

Dropbox.jpg

The Dropbox folks twittered that they had an update that fixed a few nagging Mac OS X integration features, and all were welcome to try it out. So I got it. I'll have to hold off for this evening to upgrade my other two machines in my office, but that's OK - the communication part of the app is still working great.

One of those really nice apps that does something very well, and stays out of the way. Excellent.

Good Day… Tough Commute

May 7th, 2009

MetraTrain.jpg

Today was a mixed bag of goodies for me. The day started OK, a little slow getting going, but I had a decent run and the day was looking up. I was able to get some good work done, added a few things to the code, fixed a few bugs - a good day.

Then there was the commute home.

Yikes.

The Metra train left on time, and then less than half way through the ride the lights shut off, the A/C died, and we coasted for quite a while. After several minutes of coasting, we slowed to the point they decided to stop and restart the engine. Why they didn't do this while coasting, I have no idea, but they didn't.

After a restart, we got about 200 yds. down the track and the engine died again. This time, we didn't coast nearly as far. After a few more minutes they decided that this restart of the engine would be done without the lights and A/C - as that was causing the problem. So we starting moving in hot darkness.

About a mile from the Naperville train station we died again. We weren't going that fast, so the coasting was minimal, and this time we heard over the intercom: "Battery's dead". Yummy. We sat.

Finally, someone came over the intercom and said that the engine could not be restarted and we'd have to wait for the next train to come and push us the rest of the way to the train station. After about 15 mins of sitting in the hot, dark, train the next train arrived. They then manually connected the trains, and slowly we made our way to Naperville.

When we arrived they undershot the platform, so that folks with me in the last car on the train had to move up a car to exit the train. This placed us even further behind as we had to wait for the other car to empty before we could get out.

In the end, I arrived at my car about 50 mins late. Nearly an hour late. And today was one of Nina's softball games. I was already 25 mins late, and I hadn't even started the driving portion of my commute.

Since the effect of the train stoppage was to have three trains arrive at the same time at Naperville, the effect on the traffic was going to be especially hard. I did my best, and got in line. Nothing I could do about the delays I was going to experience now.

I finally got to the softball diamonds. I just didn't want to talk about it. No reason to, I'd only get mad about it. We watched a very uninspired game from the pitching staff of both teams. It was walk after walk after walk... the only saving grace was that Nina's Team walked fewer people and ended up with the win.

There are times when I can have a great day and the commute home can really put a damper on my evening. Today was one of those days. I really hate the commute.

BBEdit 9.2 is Out

May 7th, 2009

BBEdit.jpg

My favorite Mac OS X editor - BBEdit, was updated today to 9.2. There are several things I asked for in this release:

  • ability to make ctags files from the bbedit executable
  • added better function searching in navigation bar

to be fair, there are a ton of changes, and unfortunately, not all of them I'm really happy about. The biggie I noticed right off was the fact that the status bar is now below the horizontal scroll bar, and there seems to be no way to hide the horizontal scroll bar. I need to scroll horizontally, but not all that much. The old scheme was perfect, in my mind. Sad to see it's gone.

After looking at it for a little bit I decided that since I could not remove the horizontal scroll bar, I dropped the status bar. Not what I wanted, but it seems unavoidable.

UPDATE: Interestingly, the file position "appears" to the left of the horizontal scroll bar if you move the cursor. When you switch to another window, it disappears again. Interesting... this is the single most important part of the status bar, and since it's available as I'm moving in the file, I guess it's not really "missing". Great. Kind of wild, but neat.

Amazon Introduces the Kindle DX

May 6th, 2009

Kindle.jpg

Well, I heard it was coming, and it's certainly a nice looking device. The Kindle DX is the large-format version of the new Kindle - measuring a full 9.7 inches diagonally. It includes a native PDF reader, and the ability (like the iPod/iPhone) to sense the rotation of the device and automatically go into landscape mode. Other than that, it's the second-generation Kindle.

I'm happy that my Kindle is working so wonderfully, but in a way, that's bad news for me. For as long as it's working OK, I have no reason to get a new one. I think the new version of mine is what I'd get, but it's nice to think about the bigger version and reading books. That would have been incredible in school.

Still... I'm waiting to see if Apple brings out an iPod Touch that's in the same size screen, but color, and smaller overall, and then get that and retire my Kindle. That would be a nice upgrade.