The Elegant Chaos Blog
Various thoughts and ramblings from the world of Elegant Chaos.

February 01, 2010

Dave Dribin was preaching to at least one of the converted (me), in his “Clean Code” session at NSConference today - but then I have to wrestle with very large bodies of C++ code every day, much of which was written by other people not following any of his guidelines!

Most of the stuff he said was uncontroversial, but it was amusing to see a few people in the audience bristling at one or two of the suggestions that Dave made - you could hear the cogs turning in their brains as they thought “but I do that all the time, and I’m smart, so he must be wrong”.

I can’t really offer an opinion on KVO vs Delegates, not having done enough Cocoa work, although I think it’s all a storm in a teacup anyway as he was simply offering a personal order of precedence. Having had to debug very complex systems I can see where he was coming from though. KVO sounds like a lovely way to decouple systems, but it can get scary when just “setting values” can cause a rich ripple of side effects that extends way beyond the object you thought you were playing with.

I do think Dave’s right about singletons - at the end of the day they are globals, but somehow we’ve ended up with design pattern books telling us about them, and people like Scott Meyers telling us how to implement them efficiently, and it’s blinded us to the fact.

The point that some people seemed to be missing was not that they aren’t useful (they can be), or even that they aren’t the right or pragmatic solution to some problems (they can be). It’s just that they often aren’t the best solution, and yet it is dangerously easy to fall into the trap of making them when you don’t need to - I know, I do it all the time, with the best of intentions. And Dave was right - using a singleton you can easily end up with annoying hidden dependencies and inflexibilities which you can avoid if you instead use a pattern where you pass in the services/resources that you need. And it does make life particularly hard if you want to do test driven development and unit test the hell out of everything.

I never felt that Dave’s tone was in any way preachy, but maybe some people wondered why he was telling them stuff that “we already know”. Perhaps it’s also just a very healthy skepticism in the audience towards received wisdom, which is fair enough - I’m all for that. But just because it’s received wisdom, it doesn’t always make it wrong, any more than it makes it right!

In any case I’m not at all convinced that everyone in the room does know all that stuff. There were plenty of indy developers in the room, who are working on there own a fair amount of the time, many of whom are 25 or younger. I’ve also met plenty of developers in my life who’ve been doing coding professionally for years and still haven’t got a clue!

When I was 21 and just out of college I was lucky enough to get a great job working in an university research department, writing educational software in Hypercard (with plenty of lovely XCMDs that I wrote too). It was a brilliant job and a fantastic environment in many ways, with loads of freedom for someone just out of college. At the tender age of 21 though, I was the only full-time developer and with the benefit of hindsight I realise that I missed out on a great deal of stuff that was going on at the time in the wider software engineering world, because there was nobody at work to point me in the right direction. I was totally focussed on what I was trying to make, and not on the process of how it got made. Things are a lot better now than they were in 1992 of course, and it’s a lot easier to stay in touch with the current trends in computer science through the sort of social networking that we now have. But you still occasionally need people to tell you stuff, even stuff that you’re supposed to already know.

There’s definitely no harm in being reminded of some of the basics from time to time, and having some of your assumptions challenged - whether you’ve been doing programming for 1 year or 5 years or 30.

more...

For a couple of weeks the Console application on my laptop has been crashing every time I started it up. This was a bit weird, and also very annoying, since I use it from time to time whilst developing, and to check that the system isn’t doing anything particularly heinous.

The stack for the crash log appeared to be in a call to the file system, so I figured that the problem was file related in some way. I tried removing the Console preferences, to no avail.

After a bit of thought, I realised that I could probably use Instruments (part of Apple’s Developer Tools suite) to work it out.

So I launched it, chose the “File Activity” template, and set it up to run Console. This is a great way to see what an application is doing with files.

Lo and behold, the last thing Instruments did was open a file in /var/log/, then repeatedly try to open some file in /.vol/.

Doing a quick ls of /var/log/ revealed a symbolic link to something that I thought that I had removed (some crappy VPN software called SecureClient that I used to rely on but don’t any more as it doesn’t work on 10.6 anyway). Further investigation revealed that the symbolic link pointed to another symbolic link, which pointed… to itself. That would do it!

All in all it took about 5 minutes to find and fix this crash once I realised that using Instruments was more sensible than just sitting around guessing what might be causing Console to crash…

more...

January 13, 2010

I posted last week about running Doxygen from XCode using a custom build step.

I originally found a nice article on the Apple website here which describes how to do this, but it needed a little bit of tweaking, and wasn’t great, so I’ve improved the process a little bit.

First of all, I moved the bulk of the work into a script file, so that I can reuse it in multiple projects. This seems more sensible than cutting & pasting into every project. DRY principle!

I also decided to use a standard layout, relative to the project file, which meant that I could cut down on the number of variables that needed defining per-project.

My custom build step now just has to define a couple of variables and call on to the script.

You can find my version of the script here:

http://github.com/samdeane/code-snippets/blob/master/scripts/build-doxygen.sh

It could be cleaned up a lot more - it’s basically copied from Apple’s script then hacked a bit - I didn’t write it with public review in mind! One thing I fixed in the script was support for projects that have a space in their name or the name of a containing folder. Bloody unix programmers!

Second, I was annoyed by the output of the script, so I piped it into a file.

Finally, I was also annoyed at having to wait for the script to complete. Rebuilding the documentation each time is useful, but it’s not like you actually want to go and use it immediately.

So, I tweaked the build step to run it in the background.

Now my build step looks like this:

${WORKROOT}/scripts/xcode/build-doxygen.sh > “$TEMP_DIR/doxygen.output.log” 2> “$TEMP_DIR/doxygen.log” &

$WORKROOT is a variable that points to the root of my development folder - you can just replace it with the path to the build-doxygen.sh script file.

The script file itself relies on one extra variable - $DOXYGEN_ID - which I define in the project settings. It uses this to name the documentation bundle - so you should set it to something appropriate for the product - like com.yourcompany.yourproduct.

If you want to see the output of the script, you can add a second line:

open “$TEMP_DIR/doxygen.output.log”

This will launch Console and open the log file. Console is smart enough to update as the log file gets filled in, so it works even though the script may not have finished running by the time you open the log.

Update: one more thing…

By default XCode runs the build step every time. You can tell it to be a bit smarter by telling it what the input files and output files are for the step; it will then dependency check them.

I set the inputs to:

  • $(SRCROOT)/Code
  • $(WORKROOT)/scripts/xcode/build-doxygen.sh

And the output to:

  • /Users/$(USER)/Library/Developer/Shared/Documentation/DocSets/$(DOXYGEN_ID).docset/Contents/Info.plist

Now, if you do something that doesn’t change the source code, the documentation shouldn’t rebuild.

more...

I was wondering whether to use HeaderDoc or Doxygen for Objective-C project, and after a bit of googling I get the impression that HeaderDoc is on its way out.

I found a nice article on the Apple website here which describes how to get XCode to run Doxygen for you as part of your build, and turn the results into a DocSet which XCode knows about.

It works rather well, and the documentation for my test iPhone project now shows up in XCode along with the standard Apple sets.

One slight issue - I had to edit the script a bit to cope with having a space in the path to your project. It also has rather verbose output - adding –silent to the make command helps a bit, as does altering the doxygen.config to run quietly. Unfortunately the commands in the make file that Doxygen generates still seem to spit out a fair amount of crap even if everything is working.

One other problem - XCode can’t seem to find the documentation for a type when I option-click on it, in the way that it would do for an Apple type. This may just be a question of needing to rebuild my indexes though…

more...

Over the holidays I’ve been messing about with the iPhone SDK, just for the hell of it.

I always prefer to have a project in mind when learning new tools, but I didn’t have much time, so I fairly randomly decided to do a little countdown application - something that tells you how long you’ve got before Christmas (for some reason this topic was on my mind).

The app itself was pretty simple to get going (less than a day), and doing the UI for the preferences has proved to be far more time consuming than the actual functionality! Once again I’ve been reminded how much fun it is to work with Objective-C / Cocoa.

If this had actually been intended as a commercial prospect, I’d have checked the iPhone store first, but luckily I always viewed it as a made-up project for test purposes only. Having said that I thought that I might conceivably post it to the store, just for the hell of it, so I went to have a look at the competition.

I figured that it was a totally unoriginal idea, so there’d probably be a few up there already. I wasn’t prepared, however, for there to be about forty! What’s more, I’d say that over half of them are paid apps (though costing only a dollar in all cases).

This is quite boggling, and it makes one wonder. Does anyone ever pay for these apps? Some of them have reviews, in some cases quite positive reviews, which suggests that they do. There are supposed to be more iPhones out there than Xbox 360s and PS3s put together. That’s quite a big market, but is it really big enough for 40 applications competing for a tiny and almost pointless niche? I’d love to know if anyone has sold more than 100 copies.

I guess the moral of the story is to check the store before you put any serious time into an application. Although, perhaps not. Perhaps the moral is to check the store, rip off the good features of your competition, then do the app anyway because it’s a big, big, market. Or maybe not!

more...