Archive for the ‘Tips’ category

Messages to Nowhere

January 3, 2008

This article has been updated, and moved here

Advertisements

What Quality Means

December 18, 2007

I was blown away when I read the first part of this talk given by Joel Spolsky at Yale, because it so totally nails problems I’ve seen at Microsoft and problems at my alma mater.

I was also reminded of Will Shipley’s excellent article on the limitations of unit-testing.

Crash Logs

December 7, 2007

Daniel Jalkut on how to get the most out of crash logs. It’s good advice.

Actually I do have one big issue with the article:

If there’s one behavior of your application that you should focus on eliminating, it’s the behavior of crashing. Above all other “nuisances,” this is the one that is absolutely unacceptable.

But preserving someone’s data is more important then crashing. Having to rewrite your paper because your PC devoured it is worse then crashing. Crashing may be the worst “nuisance”, but there are more important bugs to squash first. However that is a topic for another time — we all agree that crashes are a problem should be fixed.

Although Daniel shows how to synthesize debugging symbols from hex-address, I think it’s worth considering leaving debugging symbols in your shipping app.

The reasons for [building applications without debugging symbols] are mostly to keep the shipping application as small as possible, but there are also some good reasons to hide the symbols if they reveal too much about your business strategy.

I can’t say anything about your business strategies, but removing information that can help you diagnose problems “in the field” seems like a very bad trade-off for slightly smaller files.

Hard-drives cost about $0.30 per gigabyte (GB), and the price is still falling fast*. Because the GB is the unit hard-disks are sold by, I am going to use it instead of MB or KB; I think it puts file-sizes into the right perspective.

Today’s applications are “big”, for a very good reason. That article says it better then I can, but the gist of it is that megabytes are cheaper then air and bigger programs can do more, making them more useful (the cost of a GB of storage space has fallen over 20 fold since the article was written, by the way).

The largest program I use every day that was built with debugging symbols on is EyeTV. It weighs in under 0.11 GB, and I don’t consider that “bloated”, because I get good value for my 3 cents of disk-space. Stripping debugging symbols with strip makes it 0.0076 GB smaller. That translates into $0.002 worth of hard disk, that could store 13.7 seconds of TV . And that is insignificant. A few thousandths of a GB make little difference, and that’s all stripping debugging symbols will get you.

Of course, this is all academic if no one ever sees the crash-logs. Unfortunately, developers know, that’s the current crappy state of affairs. Crash reports are sent to Apple, and only Apple. The developers who wrote the program — the ones who could best fix the problem, and who desperately want to know about it, are completely out of the loop.

If Apple passed crash logs on to developers, everyone would win. Developers would be able to squash more bugs in less time. Users would have a better, more productive and bug free, experience. Apple could sell those improvements. Microsoft already does this, and it seems to work well for them. Most people are unaware of this SNAFU, and probably think that reporting the crash to Apple gets the information to the right people. I don’t know if educating people about the issue would light a fire under Apple, but it might.

—-

If enough people start using flash memory over current magnetic-platter harddrives, then the price-per-GB ratio could change, because flash is currently about 100x more expensive (per GB). But the trend of the current storage-medium’s price exponentially falling will continue

Flash-based notebooks are already here, but they aren’t popular, yet.

But by the time flash-based computers become popular, their cost-per-GB will probably be as good, or better, then full-sized hard drives of today. Tiny hard-drives, using conventional magnetic platters, like the ones in the iPod, are also a compelling alternative to flash.

Useful MacOSX Terminal Commands

November 16, 2007

This post has moved here.

Assert Outlet Connections

October 16, 2007

This article has been updated and moved here.

Better AppleScript Through Expressions

October 13, 2007

When writing a short AppleScript to complete a specific task, do not write a procedure that checks if A exists, then operates on it if it does. Instead, write an expression that operates on A, and ignore any exceptions caused by A not existing. Surrounding the statement in a try-block will ignore any exceptions it generates. The where and whose commands can help. This almost always leads to cleaner, and faster, AppleScripts.

Here is an example, a re-write of code in EyeTV version 2.5 (if you have it, you can find this script at EyeTV.app/Contents/Resources/English.lproj/EyeTV\ Help/openreadme.scpt).

When run, this opens a readme inside the EyeTV application bundle, iff the EyeTV application is running. I did not write this, and I do not know exactly how it is used, or what constraints it was written under — just what it does.

on run
set readmePath to "Contents:Resources:English.lproj:EyeTV Help:eyetvreadme.rtfd"

tell application "Finder"
 set allApps to every application process
 
 repeat with i from 1 to number of items in allApps
  set thisApp to item i of allApps
  
  if creator type of thisApp is "EyTV" then
   open file (((application file of thisApp) as string) & readmePath)
   exit repeat
  end if
 end repeat
end tell
end run

Re-writing the code by making it an expression that assumes the correct application process exists has a dramatic difference.

on run
try
 tell application "Finder"
  set theEyeTVProcessBundle to file of first item of (every application process where creator type is "EyTV") as string
  open (theEyeTVProcessBundle & "Contents:Resources:English.lproj:EyeTV Help:eyetvreadme.rtfd") as alias
 end tell
end try
end run

We no longer need if or repeat blocks — they are procedural constructs that were used to find the correct application process, and guard against trying to open a file that does not exist. (I also removed the variable readmePath because I think the a path to “eyetvreadme.rtfd” is clearly a readme-path).

But it gets better. We could try removing the run and try blocks as well, and just ignore any errors the interpreter complains about. That brings the the script down to four lines. We can make it one-line: tell application "Finder" to open ((file of first item of (every application process where creator type is "EyTV") as string) & "Contents:Resources:English.lproj:EyeTV Help:eyetvreadme.rtfd") as alias, but I think that makes the script too hard to understand, because the name “theEyeTVProcessBundle” documents the long expression needed to reliably find the application bundle of the running process.

One line or four lines, that’s still a big reduction from 13 lines. Now it’s short enough to embed directly in Cocoa code with NSAppleScript.

Here’s another example. This is from IMLocation‘s uninstaller code, it It removes the IMLocationHelper from the list of items that will be opened at login. Here’s the original code:

tell application "System Events"
 if (login item "IMLocationHelper") exists then
  delete login item "IMLocationHelper"
 end if
end tell

Applying the approach of re-writing the procedure as an expression

try
 tell application "System Events" to delete (login item "IMLocationHelper")
end try

Taking things a step further, by removing the try-block, and just ignoring errors when running the one-line script: tell application "System Events" to delete (get login item "IMLocationHelper"). This makes a big difference in the clarity of the surrounding Cocoa code.

AppleScript is a pretty poor language on it’s own. Usually I see it being used to get some specific thing done. In other words, generally AppleScripts are essentially expressions, used to get or set a single value; rarely are they sub-programs. This is whyExpressions are such a good fit.

A big thanks to Uli Kusterer for correcting my doubleplusungood code! (details in comments)

Selecting Text

September 26, 2007

Here’s a helpful MacOSX feature that I finally stumbled upon. If you hold option down while selecting text, you can select an arbitrary rectangle, instead of some number of rows. A picture is worth a lot of words:
Column Selection Example
This is great for removing extraneous information from console logs (pictured), or copying just what you want. Unfortunately, it does not work in all applications, including Safari and Terminal. A damn shame, but it works like a charm with Xcode, Console, and TextEdit.