Archive for October, 2006

The best developer tool since Interface Builder

Tuesday, October 31st, 2006

Yesterday, wootest created an app called ThisService. I’ll put this disclaimer right up front: He is a reader of this blog, and he allowed me to test a prerelease version of ThisService. But neither of these facts affects the opinion that I’m about to state.

ThisService is the greatest developer tool since Interface Builder.

UNIX has an interface paradigm called the “filter”. This is an application that reads zero or more input from its standard input special-file, operates on or with the data in some way, and writes zero or more output to its standard output special-file. This simple design is amazingly versatile, and highly conducive to simple but effective IPC.

NeXT took the same concept and extended it to the GUI with what it called System Services. Some of you may have seen these; they live on in OS X, more or less unchanged as far as I’ve seen. And their operation is pretty much the same: take some input (or not), do something to or with it, and emit some output (or not).

So John Gruber, according to himself, had the idea for an application that takes a filter program and makes a system service from it, and put this idea to wootest. Didn’t take him long, apparently; I beta-tested it last night, and the app is now at 1.0.

ThisService 1.0 main window.

Pretty simple. You give ThisService the filter’s name, location, behavior, and an optional hotkey, and it will create a system service application for you.

Services are very versatile. Consider the Objective-C service, or the Copy File Path service, or CalcService, or Tidy Service. Quite a range of functions, no? But Apple does not make a very big deal of the Services system’s existence, and so the feature sits unused by most users. When’s the last time you visited the Services menu?

And yes, this is despite the fact that many Apple applications — some of them big-name, some of them more quiet necessities — provide services. In fact, core OS X apps provide most of the services on most people’s systems. This, of course, is because on the whole, nobody else knows about Services.

I think that ThisService will change all that. The fact you can now write an OS X service in Python/Perl/awk/C/$FAD_LANGUAGE in exactly the same way that you would write a UNIX filter makes creating services now trivial. So I think that we’ll see plenty of applications in the future built with ThisService, perhaps with a badge somewhere on the webpage proclaiming that fact, with instructions like this:

This application is an OS X “system service”.

  • To install it, simply drag it to your Home/Library/Services folder (first creating that folder if necessary). It will then be available in most applications.
  • To use it, choose “service-name” from the Services menu in the Application menu (the menu just to the right of the Apple menu).
  • To remove it, take it out of the Library/Services folder, e.g. to the Trash.

(Feel free to copy the above instructions, even if you don’t use ThisService to create your service.)

The first wave or two of these new services will be geek-oriented. Programmers will take their existing stashes of filters that they’ve created (such as mine) and make services out of them and put them on their websites. Thus, the first influx of service users will be geeks (including, but not limited to, other programmers).

But then I predict a larger resurgence in services. People will start making new services from other filters that have broader utility, like sort. There may even be a new attraction to making services directly, either from scratch, or from a UNIX filter but with a GUI on top to specify options (i.e. not using ThisService). And then I think the larger, non-technical userbase will start using services.

It will be a great day.

How to use svn merge

Sunday, October 29th, 2006

A number of my fellow Adium developers have observed that svn merge is hard to use. I think the main problem is that the command is quite general (it can be put to several different uses) and the documentation not particularly clear. In order to promote better understanding of the svn merge command, here’s what I know about it.

The command in a nutshell: svn merge is essentially svn diff $ARGS | patch -p0; the only real difference is that svn merge will handle addition, movement, and deletion of files, whereas patch won’t.

This now having been stated up front, let’s get into details.

Summary of tasks and how to do them

  1. svn merge sourceURL1[@N] sourceURL2[@M] [WCPATH]
  2. svn merge sourceWCPATH1@N sourceWCPATH2@M [WCPATH]
  3. svn merge [-c M | -r N:M] SOURCE[@REV] [WCPATH]
  • To apply changes from another directory (branch, tag, trunk): Use format #1 (or #2 if you have a checkout of it), supplying at least the first revision (N), and the second (M) if it is not HEAD. With format #1, you should not need to be using the same repository URL as the CWD for either one or both; you should be able to merge between two URLs, or between a single URL into your checkout of a different URL.

  • To travel back in time to a previous revision: Use format #3, with -rHEAD:THEN. For example, -rHEAD:42000.

  • To cherry-pick a changeset (apply only that changeset, not any others): Use format #3, with -cTHEN.

  • To undo a particular changeset without disturbing things that happened after it (hopefully): Use format #3, with -c -THEN. Note the minus sign. For example, to revert r42000, use “svn merge -c -42000 .”. You can also use the -r flag: “svn merge -r 42000:41999 .”. This may be advisable, for clarity reasons, if you have a script that must always revert a particular revision.

    In both examples, note the “.” and the space before it. “.” means the current directory, and is used here as the SOURCE argument to format #3. It’s a separate argument from the revision, so you need the space.

  • All formats apply their changes to the CWD by default. I don’t know what happens if the CWD is not a WC. You can specify a different destination for the changes by specifying a different WCPATH (the last argument in all the formats above).

  • In format #3, the first path that it accepts is a URL or local WC path to the object you want to diff. (Remember my initial statement about svn merge being essentially svn diff | patch -p0.) The second path is a local WC path to the destination for the changes that are observed.

Updated 2007-07-12: Fixed error in traveling back in time (I had the revs backward); added cherry-picking technique.

svn help merge, in RTF

The “svn help merge” text is an invaluable summary of the command’s operation, but it’s plain-text, and therefore somewhat hard to read on a screen. To that end, I created an RTF version and printed it out, and decided to put it up here in case anyone else wants to do the same.

Observations on the Mac Pro

Thursday, October 26th, 2006
  • Wow, this thing is big. So much larger than my Cube.
  • I need a DVI-to-ADC adapter to use my ADC-based monitor. Suck.
  • The Cube effect is yummy.
  • Finally, I get to play all these games and watch all these videos without asking to use mom’s iBook!
  • It’s nice to look at my CPU Usage (not-yet-finished 0.4) and see as many as three cores (did I mention that it’s a quad?) running at 0%.
  • I no longer need hubs. I no longer need the external USB speakers (with headphone jack) nor iMic, freeing up two USB ports (exactly how many my Cube had). So now I can plug my keyboard into the first, my monitor into the second, and my printer into the third. If I still need more ports (e.g. flash memory), I have two on the front.
  • Speaking of which, I no longer need my FireWire repeater either. I can plug my iPod into the front FireWire port.
  • The headphones also plug into the front, but they jut out too far for my comfort. I’ll buy an L connector at Radio Shack to avoid me shearing off the headphone connector in the jack.
  • The drive bay covers slide down, rather than flapping open like a drawbridge. That’s cool.
  • Computer name: “Four-Sided Cheese Grater”. (Did I mention that it’s a quad?)
  • Rosetta works well. ShadowIRC (PPC-only) doesn’t seem any slower on this machine than it did on my Cube.
  • Apps that behaved slowly on my Cube (e.g. QS) are quite fast on this one.
  • OmniWeb actually launches fairly quickly on this machine. Not like Safari, though: half a bounce.
  • I look forward to doing a make -j4 (or maybe more).
  • As Colin points out, I have gone from last to first in terms of Adium committer developer processing power. (UPDATE 05:57: Andreas Monitzer, one of our GSoC students, has a 3 GHz four-core Mac Pro; mine is only 2.66 GHz. Rats.)
  • I now have a much better reason for recompiling my various command-line utilities, as I tend to do whenever moving to a new machine. This time, I’m changing architectures.
  • The Mac Pro is wider than my Cube, making it a better platform for my headphones (each ear pivots, so I can stand it up on them rather than having to hang or lie the headphones somewhere).
  • In the box, there’s a 3″ DVI–DVI cable. One end is a female DVI connector; the other end is a male DVI connector. I see no difference in pinouts; therefore, I am at a loss to explain what this cable is for.
  • There’s no Eject button on the computer; you’re supposed to use the one on the keyboard for that, but I’d rather not unplug my perfectly-good iKey just to get an Eject button. So I’ll just have to add the Eject menu extra to my menu bar.
  • No more convection cooling. ☹
  • Startup time (from *bong* to loginwindow): 18 seconds. This compares to 45 seconds for the Cube. The progress bar goes from 0 to 100% in less than a second.

Why you should use -availableData rather than -readDataToEndOfFile

Sunday, October 8th, 2006

(All of this only applies to regular files, not to “communications channels”, which I interpret to mean sockets and pipes. Also, this only matters on a 64-bit Mac; on a 32-bit system, you will run out of memory long before seeing any difference between these two methods.)

-[NSFileHandle availableData]:
“If the receiver is a file, returns the data obtained by reading the file from the file pointer to the end of the file.”
-[NSFileHandle readDataToEndOfFile]:
“The data available through the receiver up to UINT_MAX bytes (the maximum value for unsigned integers) …”

In other words, if there are more than UINT_MAX bytes in the file, -availableData will return all of them, whereas -readDataToEndOfFile will only return the first UINT_MAX of them.

Woo-hoo, T-shirt!

Tuesday, October 3rd, 2006

My Google Summer of Code 2006 T-shirt has arrived! Woo-hoo!

I feel good about Mac open source

Monday, October 2nd, 2006

(I’ve had this brewing in a VoodooPad page for some months now, and have finally gotten around to implementing it.)

I feel good about Mac open source.

Many of my fellow Mac programmers have made reusable source code available under free licenses, such that any other programmer can use it in their applications. This abundant generosity impresses me, and at this point has moved me to build a catalog of this code.

It’s organized by author name and by program name. It’s not just applications, though; plain classes are also listed, as are useful-looking images (such as my own plus/minus button images).


UPDATE 19:07: This is actually a duplicate post of an earlier draft. I’ll see about moving the comments over to the correct post. In the meantime, if you have any further comments, please post them over there.

UPDATE 19:43: Done. I ended up just renaming this post (dropped “-2” from the post slug; you’ll need to update any links to this post) and removing the duplicate post.