Ritchie Swann http://ritchieswann.com/index.php Thoughts and ramblings of a thirtysomething en-us Thu, 09 Sep 2010 05:03:12 +0100 PHP and bash ritchie@mono.org 5 Another little story about GetType() http://ritchieswann.com/index.php?file=gettype

Gosh, somebody's linked to something I wrote. Not only that, it's something I forgot I wrote about anyway. Here's the original article by Brandon Kelly, which talks about "is GetType() using reflection"?

Of course it is. What you've got to think about here is seeing your program at different levels of abstraction (which is another article for another time, but maybe not now). Let's put aside the "Manual memory allocation? We don't need no stinkin' manual memory allocation!" world of .NET for a minute and go back to good old C :


struct test
{
  int foo;
  char bar;
  void* baz;
};

Now, when this bit of code gets compiled into something the computer can run, a lot of information gets thrown by the wayside. Your executable code won't know you've got a structure called test, or members called "foo", "bar" and "baz". All it knows about are what you've got in memory. (This isn't quite true if you compile with debug information turned on, but that's another conversation for another time).

What does this look like in memory? Well, it might something like this:

0x12ac0 = foo, 0x12ac4 = bar, 0x12ac8 = baz

The reason I say might is because the size of types in C is completely undefined and up to the compiler to choose, normally based upon the hardware architecture of its target platform. Anyway, it's not important to this conversation - for now, let's just agree that this is what the structure looks like internally.

So far, so good. Now, let's consider another structure:


struct test2
{
  int foo;
  char* bar;
  int baz;
};

What does this look like in memory? Well, it might something like this:

0x12ac0 = foo, 0x12ac4 = bar, 0x12ac8 = baz

Now, if you were at address 0x12ac0, how do you know that what you've got ahead of you is a "test" or a "test2" at runtime? You can't. All you've got is some stuff in memory. This, incidentally, is why templates on C++ take so flippin' long to compile, as they have to back to the original header files again and again and recompile stuff. Everything has got to be reduced down to a layout in memory at the end of the day.

Now, let's imagine that we pass a decree that says "From now on, all structures will start with a description of their name". So our test structure above becomes :


struct test
{
  const char* name = "test";
  int foo;
  char bar;
  void* baz;
};

Now, when you arrive at address 0x12ac0, you'll have something like this that allows you to work out what you've got by looking at its name :

0x12ac0 -> 'test' 0x12ac4 = foo, 0x12ac8 = bar, 0x12acb = baz

This, in a simplified nutshell is what Reflection is doing under the hood for you. When you compile up your class in C#, you get a lot of additional information such as the class name, as per this example - plus a whole load of more stuff. This is the class metadata and layed out in a standard format that the .NET runtime understands, so it can reach in and grab the data you need. So when you call GetType, it has go and hunt through the metadata looking for the information you want.

For the two readers of this who haven't fallen asleep yet, this, incidentally, is why things like Activator.CreateObject() are slow - the .NET runtime always has to search through the metadata and find out what you're talking about. You can work around this by dynamically compiling constructors on the fly, so you only need to look up the metadata once (which is another conversation for another time).

]]>
Fri, 25 Jun 2010 14:27:34 +0100 http://ritchieswann.com/index.php?file=gettype
iPhone woes http://ritchieswann.com/index.php?file=iphone

Sorry, I'm a bit of a loose end at the moment. I was trying to browse something on my iPhone, but Safari hung and dropped me back to the main menu screen. I guess it must be time to give it a reboot. Whoever thought you'd ever need to reboot a phone?

I've had an iPhone for a while now, actually. It seemed like a good idea at the time. Then again, so did leaving a keyboard in the back seat of my car overnight once after a gig because I couldn't be bothered to lug it up to the house. (You can guess what happened .... and needless to say I've never done it since).

It's amazing how much goodwill and karma is held by Apple. There seems to be a particular class of devotee who will refuse to believe that there is ever anything wrong with anything they ship, at a level that would make the most feverent GNU supporter sit in awe.

But sadly, things just don't seem to stack up sometimes. And don't get me started on the dross in the iTunes store. (Actually, I don't need to, somebody's already done it for me....

]]>
Tue, 22 Jun 2010 13:49:24 +0100 http://ritchieswann.com/index.php?file=iphone
Don't OpenSource developers believe in regression testing? http://ritchieswann.com/index.php?file=opensource_testing

Sorry, it's Monday morning and I fancy a bit of a rant. I feel like I should be contributing to the Linux Hater's Blog than here, but what the hell.

I recently helped a site upgrade from phpBB 3.0.5 to 3.0.6 to fix a specific bug with polls that the users were having. Now, I would assume, given the difference in version numbers, that this would be a minor upgrade containing bugfixes. But no, there's a whole slew of new features, none of which I need, and a number of features simply don't work anymore. Didn't anybody test this?

To quote directly from the phpBB site:

"Active topics doesn't work anymore after updating!
Actually, it is now working even better than before. "

Now, I don't know about you, but a rash of users complaining that "I click on the 'View Active Topics' button but I can't see anything - waaah!" doesn't really qualify in my mind as "even better than before". Yes, it's a FAQ, it's easy to fix and I didn't waste too much time - but if it was that easy to fix, surely it would have been preferable to defer to the previous release's behaviour as a default rather than just break it.

Custom templates is a similar story - the design of them has changed between 3.0.5 and 3.0.6 meaning that none of my old templates work anymore. There doesn't seem to be a satisfactory answer to this on the phpBB forums either, just a bunch of people saying "well you might need to do 'x' and 'y'". Or maybe just rewrite them from scratch, which seems to sometimes be the open source way of doing things.

I'd prefer those who say a system is "release quality" to actually mean they, like, make sure the upgrade path is smooth and doesn't break stuff that used to work. Or do I expect too much?

]]>
Mon, 25 Jan 2010 10:34:58 +0000 http://ritchieswann.com/index.php?file=opensource_testing
JavaScript stopwatch http://ritchieswann.com/index.php?file=stopwatch

Today I needed a nice stopwatch utility. There wasn't one that quite did what I wanted, so I wrote one based on something similar here.

You can view the source for this here

]]>
Tue, 28 Jul 2009 12:54:42 +0100 http://ritchieswann.com/index.php?file=stopwatch
PHPBB authentication for DokuWiki http://ritchieswann.com/index.php?file=dokuwikiphpbb

Last month, I wrote a phpBB authentication module for MediaWiki. However, that's not the only wiki software out there, and another one I've come across is DokuWiki. Unlike MediaWiki, it uses file storage by default instead of requiring a database, which might make it an alternative for small, portable stuff.

Anyway, to install it, you'll need to do the following:

  • Download the source Here
  • Unpack this into the directory you've installed DokuWiki
  • Edit your conf/local.php to include the following:
    
    $conf['authtype'] = 'phpbb';
    
    // Change this to where you've installed phpBB
    $conf['phpbb']['path'] = '../forum/'; 
    
    // Important setting - this will disable
    // dokuwiki's UTF8 functions and use phpbb's instead
    define('NO_UTF8',true);
    

    The standard phpBB group names are available for ACL authentication. For an example conf/acl.auth.php...

    
    # Moderators have full access
    *    @GLOBAL_MODERATORS  8
    # Registered users have read access
    *    @REGISTERED         1
    

    ]]> Thu, 23 Jul 2009 17:14:35 +0100 http://ritchieswann.com/index.php?file=dokuwikiphpbb Thoughts for a dull June http://ritchieswann.com/index.php?file=ont

    You know you've made it as a developer when Raymond Chen answers one of your questions, without dismissing it as blindingly obvious, silly or spam.

    Mind you, I'd completely forgotten about the question in the first place, but there we go. Cheers, Raymond.

    ]]>
    Thu, 11 Jun 2009 14:25:17 +0100 http://ritchieswann.com/index.php?file=ont
    Auth_xphpBB http://ritchieswann.com/index.php?file=authxphpbb

    Well, it's been a while since I've blogged on here, due to getting snowed under with coding, but I've now got something you might find useful.

    If you run a user interactive site, you might well use phpbb as your bulletin board software, and MediaWiki for your user generated documentation. (Well, at least I've run a site or two doing this).

    There's already a nice extension here that allows MediaWiki to use phpBB login credentials, so you don't have to keep shuffling two sets of users around, but I thought it would be nice to go one further and use the actual phpBB API. This is the result.

    This extension requires PHP5.2, MediaWiki 1.11+ and phpBB3. To get this working, you'll need to do the following:

    1. Because MediaWiki and PHPBB both make prominent use of a class called 'user', and because PHP 5.2 doesn't provide a nice way of using include or require and yanking the whole lot into a separate namespace, you'll have to modify one codebase or the other to avoid conflicing class names. I recommend changing phpBB, and renaming user to phpbbuser. You will need to change the class definition and constructor in includes/session.php and the single instantiation point in common.php.
    2. Download the source here, unpack it and put it in the extensions subdirectory where you've installed MediaWiki.
    3. Add the following code to the bottom of LocalSettings.php:
      
      require_once './extensions/Auth_xphpBB.php';
      
      $wgAuth_Config = array();
      // Name of your PHPBB group
      // users need to be a member
      // of to use the wiki. (i.e. wiki)
      // This can also be set to an array 
      // of group names to use more then 
      // one. (ie. 
      // $wgAuth_Config['WikiGroupName'][] = 'Wiki';
      // $wgAuth_Config['WikiGroupName'][] = 'Wiki2';
      // or
      // $wgAuth_Config['WikiGroupName'] = array('Wiki', 'Wiki2');
      // )
      $wgAuth_Config['WikiGroupName'] = 'Wiki';
       
      // This tells the Plugin to require
      // a user to be a member of the above
      // phpBB group. (ie. wiki) Setting
      // this to false will let any phpBB
      // user edit the wiki.
      
      $wgAuth_Config['UseWikiGroup'] = true;
      // Path from this file to your phpBB install.
      $wgAuth_Config['PathToPHPBB']    = '../phpbb3/';
       
      // Localize the messages
      $wgAuth_Config['LoginMessage']   =
      'You need a phpBB account to login.';
      $wgAuth_Config['NoWikiError']    =
      'You are not a member of the required phpBB group.';
       
      $wgAuth = new Auth_phpBB($wgAuth_Config);
      
      These settings should be familiar if you've used the Auth_phpBB.php extension, though you'll notice there are a lot less options.

      Any thoughts, comments, praise to the skies or flamewars, do let me know!

      ]]> Mon, 04 May 2009 12:15:18 +0100 http://ritchieswann.com/index.php?file=authxphpbb OpenID considered pointless http://ritchieswann.com/index.php?file=openid

      Why is everybody and their pet gerbil banging on about OpenID like it's the second coming?

      Let me see, I guess this is trying to solve the problem that you can't remember 72 gazillion passwords for all the online services you use.

      Well, guess what, my browser lets me cache passwords so I don't need to. So does my IPhone. This problem was solved at least five years ago, and my current browser seems to manage quite well with it.

      I don't have accounts on any of the so-called "popular" providers listed on OpenID's site, and I can't be faffed to roll my own on here because there's no point.

      If your site uses OpenID to log in, feel free to flame me to a crisp 'cause I'll never read it.

      ]]>
      Tue, 03 Feb 2009 11:39:19 +0000 http://ritchieswann.com/index.php?file=openid
      PRJ0050 http://ritchieswann.com/index.php?file=prj0050

      Here's another totally non obvious error message you can get when building old C++ code.

      PRJ0050: Failed to register output. Please ensure you have the appropriate permissions to modify the registry.

      Turns out it's not necessarily related to permissions or the registry at all. You can simply get this if you try and register a DLL that has a direct dependency on another native DLL that can't be found. So, for example, if you have a COM DLL foo.dll that uses functions in a non-com DLL called bar.dll, and you link directly against bar.lib, you'll need to have bar.dll either in the same path as foo.dll (or in one of the other system paths) when it comes to registering it.

      Easy when you know how.

      ]]>
      Thu, 22 Jan 2009 11:47:16 +0000 http://ritchieswann.com/index.php?file=prj0050
      'Switch' considered harmful http://ritchieswann.com/index.php?file=switch_harmful

      Last night, I felt it was high time I learned some Python, since it's been around for years and since Eric S Raymond recommends it as a first language, it can't bee too hard to pick up for a grizzly old git like me.

      Now, while I can do things in three lines of python that would take several pages to do in C (which is pretty much the raison d'etre for any high level language), one thing struck me as being slightly odd - there's no switch statement. (The DBA weenies among you will know this as the SELECT CASE statement - it's the same animal). So you can't do things like:

      
      switch( viking ) {
        case 1 :
          menu = "eggs";
          break;
        case 2 :
          menu = "bacon";
          break;
        default :
          menu = "spam";
          break;
      }
      

      (At this point, all of you python lovers out there are saying : "Eggs? Bacon? Spam? You really have been drinking the python kool-aid haven't you?" Shut up.)

      And this doesn't actually strike me as a bad thing. Why's that? Well, switch is easy to abuse. Here's a popular example :

      
      switch( type ) {
        case sprocket :
          DoSprocketThing();
          break;
        case widget :
          DoWidgetThing();
          break;
      }
      
      What's wrong with this? Well basically, when you add a new type, like a grommit, you've got to plumb your DoGrommitThing into the switch block. And what are we doing here? Calling a different method depending on what type we've got? Hmm, smells like polymorphism to me. Call the object oriented police!

      And that example's a nice one. I've seen much worse, like where you don't just have one function call, but great steaming piles of code in each case block. Home baked state machine handlers are the biggest offenders for this. (Especially if they're written in VB. With nested With statements. Can you tell I've had to debug a few of these in the past?)

      Anyway, python works around the lack of a switch by allowing you to associate values with functions. Pop onto the wikipedia page above and you'll see an example. I like this, because you're abstracting away the algorithm to do the switch as a data structure. C's been doing this for years (with function pointers), but the nice thing about python is it makes this easy, and doing silly stuff hard. I mean, you can still do insane state machine abuse by using lambdas though, just it's just a bit harder to think about what code to write, so you're less likely to do it.

      I don't miss switch. Do you?

      ]]>
      Fri, 19 Dec 2008 10:42:33 +0000 http://ritchieswann.com/index.php?file=switch_harmful
      RAII and .NET go together like matches and petrol http://ritchieswann.com/index.php?file=raii_dotnet

      If you've spent any time doing C++ programming, you've probably come across the Resource Aquisition Is Initialization (or RAII to its friends) pattern. This basically is a way to avoid the faff of allocating and deallocating resources correctly, and letting C++'s constructors and destructors do the dirty work for you (especially when it comes to throwing exceptions, but that's a whole different rant....)

      If you've spent any time looking at what Microsoft have been up to in, oooh, at least the last ten years, you'll have heard of this new fangled .NET thingy. (I say "New Fangled" but it's got to be well over ten years now since Anders Helsbjerg was kidnapped at gunpoint and sped over to Redmond in a security van ... well that's the way I picture it at any rate.)

      And if you've used both, you've probably tried to slap them together so your scary old C++ code can be easily reused by your brand new C# / VB / F# / IronPython code. And therin lies madness. Here's why :

      • RAII is completely reliant on destructors firing where you'd expect them to fire. Basically, you can predict how and when they're going to be called.
      • .NET, on the other hand, don't need no stinkin' destructors. The garbage collector will free up stuff when it bloody well wants to.

      An example might help:

      
      #include <windows.h>
      
      // Error handling ommitted for clarity. You wanna nitpick about error
      // handling, go and do it on Raymond Chen's blog.....
      
      class Fred
      {
      private:
        HANDLE _hFile;
      
      public:
        Fred() { _hFile = ::CreateFile( "fred.txt", GENERIC_WRITE,
          FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL ); }
        ~Fred() { ::CloseHandle( _hFile ); }
      
        void Write( const char* message ) const { 
          DWORD written = 0;
          ::WriteFile( _hFile, message, strlen( message ), 
            &written, NULL );
        }
      };
      
      class Barney
      {
      private:
        const Fred* _fred;
      public:
        Barney( const Fred* fred ) : _fred( fred ) {}
        ~Barney() { _fred->Write( "Brillant!" ); }
      };
      
      int main()
      {
        Fred fred;
        Barney barney( &fred ); 
      }
      

      Run this up, and you'll get "Brillant!" printed to fred.txt. And all's well and good. But only because Barney's destructor always fires before Fred's. Convert this into managed C++ (an exercise I will leave to the reader) and all bets are off. If you're lucky, Fred will get destroyed before Barney, which means Barney will try and call Write() on a dangling pointer, and then demons will fly out of your nose.

      Ouch.

      So what does this mean for you, as a developer. Well, you're going to have to get busy with IDisposable and its friends. It's doable, but it's not pretty.

      ]]>
      Thu, 11 Dec 2008 11:48:01 +0000 http://ritchieswann.com/index.php?file=raii_dotnet
      Some 'Tron Classics http://ritchieswann.com/index.php?file=tron_classics

      I've waxed lyrical about the Mellotron before, but if you're wondering how it can be really put through it's paces, check this out :

      http://www.mikedickson.org.uk/mellotronworks/

      Several orchestral classics played on overdubbed mellotrons. Brillant. This is music to scare small children with. And to you, it's free.

      ]]>
      Fri, 07 Nov 2008 08:40:43 +0000 http://ritchieswann.com/index.php?file=tron_classics
      Dazed and Blistered http://ritchieswann.com/index.php?file=dazed_bass

      Have you ever tried playing Dazed And Confused (or at least the more famous version) on the bass? Specifically the riff that keeps going at the rate of knots underneath the guitar solo.

      I can do it for about two minutes tops. Then my hand hurts. Lord only knows how they managed to keep going for nearer ten....

      ]]>
      Wed, 05 Nov 2008 22:20:54 +0000 http://ritchieswann.com/index.php?file=dazed_bass
      When "safe" functions aren't. http://ritchieswann.com/index.php?file=safestring

      Recently I have been converting a lot of, ummm, legacy code to use the "safe" string functions that Visual Studio likes to whine about.. This is the sort of thing where you pass in the size of a destination buffer so the library function guarantees never to write beyond that point.

      Of course, "safe" doesn't mean "reads your mind". You can still tell out and out porkie pies to it, as I did this morning :

      
      wchar_t buf[ 100 ];
      wcscpy_s( buf, sizeof( buf ), "Hello, world!" );
      

      What's wrong with that? Well, the "safe" versions require you to pass in the number of characters, not the number of bytes (which is what sizeof will give you). So I've told wcscpy_s it can fiddle with twice as much memory as it really can. Try this at home folks, and see what crash you get!

      Moral of this story? Mind your memory allocation. Or switch to a language that doesn't involve fiddling with if throwing gobs of memory around with wild abandon isn't important.

      ]]>
      Tue, 04 Nov 2008 11:59:01 +0000 http://ritchieswann.com/index.php?file=safestring
      Some demos http://ritchieswann.com/index.php?file=demos

      I was fiddling around with acoustic guitars yesterday and came up with this tune. I remember it from an album my dad used to have. There's four acoustic guitars except for the middle section where I went a bit trigger happy on the overdubbing....

      I thought about putting it on a nospace account just because they've got an integrated player and I haven't, but it seems I created the wrong type of account, and when I tried to delete it and recreate it with the right type, I was locked out. Maybe I should have turned JavaScript on and had my mouse cursor freeze up even more.

      Or maybe I should write my own player on here. Yeah, that'll be it.

      ]]>
      Thu, 02 Oct 2008 17:57:31 +0100 http://ritchieswann.com/index.php?file=demos
      On Stack Overflow http://ritchieswann.com/index.php?file=stackoverflow_redux

      I finally got round to looking at Stack Overflow this morning.

      My initial thoughts - it's too busy. I went on three times yesterday afternoon and every time there were different questions, with updates less than a minute old, and thousands of views. There's no way on earth I can sift through that sort of information meaningfully.

      Maybe it'll take off when popular pages on it float onto Google.

      ]]>
      Wed, 17 Sep 2008 09:56:30 +0100 http://ritchieswann.com/index.php?file=stackoverflow_redux
      Rick Wright http://ritchieswann.com/index.php?file=rick_wright

      As you've probably seen on the news, Rick Wright, the only man to take on a Farfisa Compact Duo with a Binson Echorec and make it sound like it came from outer space, died yesterday evening.

      :-(

      Although his playing on Floyd albums was never particularly complex, it was well thought out. I still can't remember exactly what the last two chords are at the end of each verse of "Breathe", and you just can't do justice with Astronomy Domine on anything less than the aforementioned Compact Duo and Echorec. A Hammond does not cut it.

      Hey ho.

      He was a thoroughly likeable chap too. Shame he didn't get round to putting some more solo records out, 'cause the stuff he did put out wasn't too bad.

      ]]>
      Tue, 16 Sep 2008 12:18:35 +0100 http://ritchieswann.com/index.php?file=rick_wright
      Multiple Monitors http://ritchieswann.com/index.php?file=multiple_monitors

      Most developers who are respected use at least two monitors. In fact, three monitors is becoming de facto at lots of places, so even if you're still on two, you're besides the times.

      Nobody worth anybody's time gives developers a single monitor these days, and those that do are probably the places that make them wear a tie, and sit in a cubicle debugging spaghetti VB4 code all day long.

      So why the frig do I still get applications that can't remember which monitor I last used the application on? I leave one monitor in an IDE, and one monitor for test. When I run an app on the test monitor and close it, I want it to come back on that monitor. It's not too hard you know.

      Not supporting multiple monitors drives me nuts. Stop it. Now.

      ]]>
      Fri, 12 Sep 2008 12:31:07 +0100 http://ritchieswann.com/index.php?file=multiple_monitors
      CXX0072 http://ritchieswann.com/index.php?file=cxx0072

      Have you ever got this message when trying to view a variable when debugging a Visual C++ project?

      Error CXX0072: type information missing or unknown.

      I did recently. Turns out that on a pruning exercise a while back, I accidentally deleted a bunch of ATL/MFC program databases. You don't wanna do that, as it then means the debugger hasn't got the faintest idea this bunch of bytes at this address is really this particular flavour of CString.

      Since googling for CXX0072 doesn't bring up much, I thought I'd mention it here in case some other poor schmuck is stuck.

      ]]>
      Tue, 09 Sep 2008 12:25:14 +0100 http://ritchieswann.com/index.php?file=cxx0072
      Superstition is in E Flat http://ritchieswann.com/index.php?file=superstition_key

      You know something, I'm a stickler for playing songs in the right key. When I see cover, tribute and function bands play a song that's obviously supposed to be in the same style as the original artist but in the wrong key, it drives me up the wall. (Is it to do with having relative pitch, musical training, an autistic trait, blind pedantry, or a combination of all the above? Comments welcome.)

      There are a number of offenders in this field, but the most obvious one is Superstition. The original recording is in E flat, and for a very good reason - you can play the distinctive clavinet riff using just the black keys, which is easier to do than using any white keys if you can't see what you're doing. Close your eyes and try it! (I really don't think I need to explain why that's relevant, do I?)

      Anyway, can any band play it in this key? Not a chance. The worst offender is playing in E, but I've seen at least two bands that put it in D, and one in F (which actually sounds the best of all the "wrong" keys, oddly enough).

      The biggest excuse for doing this is that E flat isn't a very nice key for guitarists to play in. Cry me a river, guitar players. Go and learn the alto or bari sax, then try and play something in concert E major - a nice key for guitarists. You'll be in C sharp major. That's a sharp on every single note. Saxophonists will thank you for playing in keys with flats. Anyway, what's stopping you sticking a capo on the first fret and playing it in D?

      The second biggest excuse is that bottom E flat is one note too low on a standard four string bass. If you don't want to shell out for a five string, there's a workaround. Drop the bottom string down one fret using your tuner (ummm, you do use digital tuners, right?) while the opening drum loop is playing. I've done it, and you can too.

      Let's a get a bit more respect for E flat, people!

      ]]>
      Thu, 04 Sep 2008 11:43:23 +0100 http://ritchieswann.com/index.php?file=superstition_key
      Me, too! http://ritchieswann.com/index.php?file=me_too

      Have you ever noticed the following on blog comments or discussion fora?

      • "Me too!"
      • "+1 fred" (or whoever's post). Or, as a variation on a theme, replace 1 with n where n may be 10, 100, 10000, MAX_INT or some other really large value depending on how much wisdom is being perceived as spouting.
      ...and then nothing else in the post???

      Am I only the person in the universe who is a little irked by this? By all means say you agree with somebody, but please try and add your own thoughts and words if you can!

      Yeah, so you agree with the poster who thinks writing your code in one big main statement littered with gotos is bad programming practice. Now tell us something we don't know.

      ]]>
      Tue, 02 Sep 2008 10:13:10 +0100 http://ritchieswann.com/index.php?file=me_too
      On MySpace http://ritchieswann.com/index.php?file=myspace

      I've recently been looking at automating some stuff on a Myspace profile.

      For those in the know, this is where anybody who's a) under 20 and b) not technically minded go to hang out with their buddies and put up pictures of themselves and their cat and hope anyone notices. Um, gosh. This stuff got boring when we all discovered NCSA Mosaic could do inline images in about 1992.

      But that's not my real rant, which is the sheer amount of data that gets thrown over the wire on a MySpace page. It takes forever to load up compared to your vanilla HTML page, and really chokes on my ol' Thinkpad, whereas most sites run absolutely fine. The most obvious offender is the page that has a completely unreadable font for the first 40 seconds, until suddenly the background picture slots into place and you can actually read things without having to highlight them.

      And try sticking a page through the infamous W3 Validator and see what breaks. (Yes, I know this site has got W3 errors too, it's on my todo list to fix and it's run in my spare time anyhow....) I haven't tried looking at a MySpace page under Lynx yet, but that might make interesting viewing.

      Or have I missed the point and it's, like pink mobile phones, really designed for a whole different demographic (ie: people born after NCSA Mosaic was released.)

      ]]>
      Fri, 22 Aug 2008 14:13:05 +0100 http://ritchieswann.com/index.php?file=myspace
      Touchpads http://ritchieswann.com/index.php?file=touchpads

      I just can't get the hang of touchpads on laptops. My main laptop is a good ol' Thinkpad with a nipple, which I find is much easier to control the pointer over a small and finely grained area.

      With a touchpad, though, I seem to spend all my time dragging my fingers round and trying to line the pointer up with the place I want it to go. If it wasn't for keyboard shortcuts, I'd be stuffed.

      Anyway, nipples take up less real estate, so you end up with a smaller laptop overall, which can only be a good thing.

      Am I using touchpads wrongly? I dunno. Any ideas, you lot?

      ]]>
      Wed, 20 Aug 2008 10:05:52 +0100 http://ritchieswann.com/index.php?file=touchpads
      Lee Limerick http://ritchieswann.com/index.php?file=lee_limerick

      Recently, I have been debugging code while listening to an album by Lee Limerick, of whom I know next to nothing, other than he's done one good album (albeit with a naff cover) about ten years ago and googling for his name turns up nothing but a few outdated adverts for it.

      Anybody out there know anything more? Is it a great lost album?

      ]]>
      Thu, 14 Aug 2008 11:07:09 +0100 http://ritchieswann.com/index.php?file=lee_limerick
      What is ASP.NET? http://ritchieswann.com/index.php?file=asp_net

      As I mentioned earlier, this blog is done in PHP on Linux, but just like cumquats are not the only vegetable, these aren't the only way to get a set of dynamically generated web pages up and running. There's another popular way of getting web development done, and that's by using ASP.NET.

      (As an aside, you might hear people talking about a "LAMP" stack versus a "WIMP" stack. That's "Linux+Apache+MySQL+PHP" and "Windows+IIS+MySQL+PHP" respectively, which are two popular ways to get open source web apps up and running. LAMP is pure open source tree hugging rms loving nirvana, where WIMP is more pragmatic if you've already got a bunch of Windows servers that work fine, thanks for asking and nobody's really got time to educate the MCSE certified engineer how to set up ... shudder ... a Linux Box. Who said blogs weren't educational then?

      Anyway, there's nothing wrong with ASP.NET. It's quite a nice compact way of generating dynamic web pages. Works pretty much "out of the box" on Windows and IIS.

      Actually, scratch that, I've changed my mind. It works too well out of the box. Remember the good ol' days of VB3 where you could just drag stuff onto a form and it worked. Well, you can do that in Visual Studio for web apps, and have been for some years. Works great.

      Only the performance tends to suck. Yes, it's our old friend the leaky abstraction! Put a grid on a form. Make sure it's using the ViewState to store its data. Stick 500 items on it. Now connect to the app from another browser. Ouch!

      HTTP is a stateless protocol. For those at the back, that means that once the server has fired the page at the client, it's history. It's been and gone. It's yesterday's news. This means if you want to store some state, you have to cheat, which generally involves the browser telling the server something like, "Yoohoo, I'm the same client that was connected 10 seconds ago, just thought I'd let you know I've clicked on this button" and the server being able to pass back the modified page in response. If you have to remember lots of data, you've got to either pass the data back and forth every single time you change something (that's ViewState), or rely on the server caching some of it and passing in some previously agreed key to get it back (that's SessionState, which has its own set of problems I may come back to later....)

      Anyhoo, use ASP.NET, but make sure you grok HTTP first, otherwise you'll produce apps with the performance of an arthiritic slug, and you won't know why.

      ]]>
      Wed, 13 Aug 2008 11:46:49 +0100 http://ritchieswann.com/index.php?file=asp_net
      Do you still run anti-virus software? http://ritchieswann.com/index.php?file=non_admin_virus

      A while back I ranted about everybody running as administrator for some bizarre reason. I haven't done this for some time now, and I haven't really noticed any problems. Well, not from my software which tests these things now.

      With this in mind, I decided my latest installation of AVG was too dang slow and big, so I got rid of it. So now I have no anti virus software on my desktop PC.

      I'm not really that terrified, since I don't have any anti virus software on my laptop and never have done, and I've never got a virus. Truth to be told, I don't really look at that many websites, most of the ones I regularly go on have an RSS feed, and I don't fancy Angelina Jolie. And I still get my email via pine, on which running a typical macro virus is actually something of a challenge.

      And of course I run as non admin. Okay, it's possible to trash my user account via a nasty piece of JavaScript, but did I mention I disable that too most of the time?

      ]]>
      Tue, 05 Aug 2008 18:04:10 +0100 http://ritchieswann.com/index.php?file=non_admin_virus
      More Mellotron stuff http://ritchieswann.com/index.php?file=more_tron

      A few weeks back I was waxing lyrical about the infamoue Mellotron, the wacky tape based sampler from the 60s and 70s.

      Well, somebody's made a version with Walkmans. (Or is that Walkmen?) Brillant!

      And if that wasn't enough, there's a video of the thing too.

      ]]>
      Thu, 24 Jul 2008 22:22:58 +0100 http://ritchieswann.com/index.php?file=more_tron
      Rites of passage : Generic SQL http://ritchieswann.com/index.php?file=sql_generic

      Now, I don't claim to be the world's greatest SQL guru. In fact, I'm always a bit suspicious of my own SQL skills. I mean, I can get the tradoffs with maintainability and speed when it comes to design, and tune performance if I need to, but deep down it's all a bit freaky voodoo, compared to, say, grokking the stack and heap enough to know why my C code has printed another segmentation fault message without giving up and using a half decent language for strings instead.

      Anyway, it seems anybody who's ever worked on SQL has had this thought at one point.....

      "Look at all these hard coded table names! How might we maintain the system for future requirements? Woe is me. I know - let's make the data storage totally generic. We'll have a single table called stuff, with two fields type and data, where data can be absolutely anything you bally well like. Take that, backwards compatibility police!"

      So then you knock up your generic data layer (preferably with spelling mistakes thrown in) and off it goes, merrily serving data. And all is well.

      Until you have to debug the data layer. Then suddenly unravelling what the hell all those blobs mean can be a daunting experience. All of the 90,000 fields in that one table look all the same - what the frig does any of it mean.

      I've seen at least four projects start off like this, and they've all ended in train wrecks (or at least a nicer solution put in place).

      If you've been there and done that, you have my sympathies. There are ways of making your data layer more adaptable (hello LINQ and ActiveRecord ) but making a big ol' "generic" table just ain't one of them.

      ]]>
      Thu, 24 Jul 2008 20:50:03 +0100 http://ritchieswann.com/index.php?file=sql_generic
      HTML layout, tables and CSS http://ritchieswann.com/index.php?file=html_tables

      Today, I'm going to sound off on what might be described as a flame. I'm not intending to knock or bash anybody who does hardcore web based front end development. I don't do that much in the front end, and I just really think I don't "get" something that I'm sure somebody good at explaining things to four year olds could relay across.

      Anyway...... If you go up to your browser right now, and click on "View Source", you'll notice the layout is predominantly table based. There are a few divs to make other odds and sods work, and some CSS to make the fonts and colours the way I want them (or in the case of comments, to faff about with easily until I'm happy with them), but it's mostly good old <table>, <tr> and <td>. And I don't think there's anything wrong with that at all.

      Now, at this point hundreds of web designers are reaching for their Flamers' Thesaurus and composing an enranged rant. "You idiot. Tables are the root of all evil! They are the goto of front end design! How on earth can you still be using such antiquated crap? Table based layout is so 1996. Get a book on CSS and join us in the 21st century if you can be bothered!"

      Here's why I like tables :

      1. They're easy to code
      2. They're easier to get working on more browsers

      "Whaddya mean they're easy to code?", says everybody. "Come on, are you seriously telling me:

      
      <table border="0">
      <tbody>
      <tr>
      <td align="left">Side 1</td>
      <td align="left">Side 2</td>
      </tr>
      </tbody>
      <table border="0">
      
      is EASIER to code than
      
      .left {float: left;}
      .right {float: right;}
      <div class="left">Side 1</div>
      <div class="right">Side 2</div>
      
      Have you finally lost it?

      I didn't say easier, I said easy. Do you honestly think there is much difference in those two files? I mean really. Come on. Go and look at the i386 boot code in the Linux kernel source, then come back to me and say this is big major architectural important stuff. Anyway, tbody is redundant, and so is all that whitespace, so I'd compress that lot down to a line or two anyway.

      But the real secret sauce here is that I generate my HTML server side and have functions to generate the HTML cruft for me. So in actual fact my code looks more like:

      
      WriteLayout( 800 /* width */ );
      WriteEntry( "left", "Side 1" );
      WriteEntry( "right", "Side 2" );
      WriteLayout();
      

      So the HTML you get out the other end looks a bit mangled and hard for a human to read. So what? Have you tried looking at a core dump lately? That's mangled and hard for a human to read, but I don't see anybody whining when your buggy C code barfs and spits one out. (Well, they do whine, but not because of readability).
      Look, I'm sorry if you're an HTML / CSS guru and don't care what a pointer is, but arguing that CSS is better because it fits in with your skillset is just a strawman argument for those of us who've done more things.

      In fact, my HTML generator might well have been implemented to generate CSS lookups instead of tables, if it wasn't for point two of my argument which is tables friggin' work! Go and find a nice up to date modern site with CSS and divs all the way for layout, and see how much crap there is to support IE6, IE7, Firefox, Safari, Opera, oooh I can't keep up. You put a site up with tables, pull it up on an iPhone and it works. You pull it up on Lynx to check that Google will crawl your content nicely and it works. I don't know what more I need to say - life is too dang short to spend it writing stupid compatibility hacks for all the browsers out there in the world.

      So there you go. That's today's rant on web usability. Of course, if I've missed something blatantly wrong here, you will let me know, right?

      ]]>
      Fri, 11 Jul 2008 09:50:53 +0100 http://ritchieswann.com/index.php?file=html_tables
      Stating the obvious http://ritchieswann.com/index.php?file=obvious_comments

      You know what's worse than Gollum comments??

      Things like this :

      
      // Increment the variable 'foo' by 1
      foo++;
      

      I think we've all done this at one point another. But enough already. Comments are supposed to describe things you cannot see just by looking at the code. Things like 'this weird stuff is to get around a bug in Blaze-O-Matic where it doesn't conform to the spec' so that the person after you doesn't think "which dweeb wrote this?" and accidentally re-introduce your bug without realising.

      If code tells you what, comments tell you why.

      Good commenting is hard, but if you stop stating the blindingly obvious, it's a step in the right direction.

      ]]>
      Thu, 10 Jul 2008 09:27:26 +0100 http://ritchieswann.com/index.php?file=obvious_comments
      Languages are for humans. http://ritchieswann.com/index.php?file=languages_are_for_humans

      There's a lot of programming languages out there. And almost by definition, that means there are a lot of religious wars on there. Just pop onto here and say something constructive about Visual Basic. Or have a look at this. (Warning - you may find dodgy PHP and Visual Basic on this thread. Sorry.) Or wax lyrical about the extensiveness of STL and boost to somebody who's up to their ears in kernel alligators. (Yes, I'm thinking of you again).

      Every other year, there's a language in vogue. Back when valves were used in places other than snobby hi-fis and Marshall amps, it was Fortran. Skip forward to a time when this was in fashion and it was C++. Then it was Perl, then Java, then Python, then Ruby (preferably 'On Rails' if you please), and lawd only knows what it is now ... anyone for Croquet?

      Why have we got all these friggin' languages?

      Simple. If you didn't have them, you'd be programming in machine code. Not even assembler. Raw hex. Yeah, you could theoretically get the most super super top performing code if you do stuff that way - if you ever managed to get your code written quickly enough, and then debugged.

      Aha - now we're onto something. We all use languages because they make our code easier to debug. Not read or write - debug. It's pretty easy to for a seven year old to write10 PRINT "Hello World" 20 GOTO 10, and it runs pretty fast too (well, maybe not all the time...), but try writing something that could really do with a bit of recursion, and your head will start to hurt. (Well, mine would). Especially if you've got your algorithm wrongly implemented and need to change it.

      In a language, you're trading performance for not making your head hurt. It's great popping a few lines of code into Rails and your website pops out the other end, but it won't scale as well as a really tightly optimized CGI app written in C++. And you might think you're oh so clever with your STL and boost app that uses no pointers at all, but it will not run as fast as raw C. This may not be an issue for you, but it is for Linus. All you're doing is trading off performance for less head hurting (and to be honest, having stepped through the STL source in late night debugging sessions, I'm not even convinced about the head hurting bit...)

      Learn a couple of languages, and understand the tradeoffs between them. Then you'll be less suspect to religious fanboyism.

      ]]>
      Tue, 08 Jul 2008 11:07:05 +0100 http://ritchieswann.com/index.php?file=languages_are_for_humans
      Human debuggers http://ritchieswann.com/index.php?file=want_debuggers

      Recently I caught sight of a trial interview question : Implement stdarg.h. Just to briefly explain, this contains some stuff you can use to extract values from a function in C that takes a variable number of arguments. That's what the ... in function declarations means - printf being the classic example. Wear a hard hat.

      "Good question", I thought. And I wondered why that was.

      Now, I'll be the first to admit that in this day and age, it's a bit old hat. We have nicer abstractions to deal with this sort of thing these days. You can use the params keyword in C# and it won't crash when you mess up. (Actually you could say that about a lot of C - 'mess up and you crash'. Anyway....)

      Yeah, so 99.5% of the time, you don't need to worry about this stuff.

      It's the remaining .5% that'll bite you. If it breaks, the customer don't care if it's in that .5%, if the clam steamer don't work there's gonna be hell to pay!

      Sure, when you're writing code, you're never going to use stdarg.h in a month of Sundays - and if I catch you writing it, I want a damn good excuse why. But when you're debugging code, all bets are off. You only need one bit of code right down at the bottom to go pear shaped and you're in trouble. (Especially if you crash deep inside STL and your debugger throws you into something that looks suspiciously like line noise. Anyhooo.....). And the last time I looked, sprintf was still doing the rounds, even if it's neatly tucked away underneath pages of C# wrappers. (And if you're not writing it, somebody else is. Probably in an office in Redmond.)

      So - if somebody asks you about weird things like stdarg.h, they're not really interested about why you'd use it in this day and age. They just want to throw you into a situation that's comparable to a really hard bug report landing on your desk, and seeing if you sink or swim.

      And if you're gonna sink, get some armbands!

      ]]>
      Thu, 03 Jul 2008 21:01:16 +0100 http://ritchieswann.com/index.php?file=want_debuggers
      On hiding menu items http://ritchieswann.com/index.php?file=menu_items

      It's seems you're not a real blogger until you've claimed that Joel has jumped the shark. Here's my contribution.

      Pop off for a minute and read this. I'll be asking questions in a minute.

      Done that? Good. So what did it say?

      Umm, you should leave a menu item enabled, and if the item doesn't work, display a message telling the user why.

      Good, I'm glad you were paying attention. Trouble is, when you actually do this, this is what the user really reads in their head :

      Ding, thanks for playing!

      Ouch. Okay, having a disabled menu is kicking the user in the face, but at least it kicks them a lot sooner than a frightening error box.

      Now my recommendation is don't put up the dang menu item in the first place. Don't make it enabled or disabled or decorated with dancing hula girls (although if you can do that, I'd love to know how....) Just get rid of the damn thing. The less stuff you have on screen, the less your end user is going to get stumped by.

      ]]>
      Wed, 02 Jul 2008 12:48:39 +0100 http://ritchieswann.com/index.php?file=menu_items
      Debuggers http://ritchieswann.com/index.php?file=debuggers

      If this was a Four Yorkshiremen sketch (and if that type of sketch or parody thereof hadn't been done to death for at least the past fifteen years), I'd probably say something like this :

      • Debuggers? Luxury, in our day we 'ad to use printf!
      • printf? Eeh, you were lucky, we 'ad to use toggle switches on mainframe. I had to get up at three in the morning to throw the hardware hack switch, watch the teletype printer for fifteen hours a day, thruppence a week, week in week out....
      • Toggle switches? I 'ad to work on embedded firmware t'size of matchbox fixing all my bugs by guessing, and if I got it wrong my boss would slice me in two wi' chainsaw.
      • Aye.

      Ahem. Anyway, I think everybody's in agreement that debuggers are a huge leap in productivity. In my early days as a C developer, I use to test code in Borland C 3.1 (remember that?) and then port it to Unix, as Borland's debugger was great. (Especially the memory windows which I used a lot to track pointer related bugs.)

      The trouble is, the debugger's an abstraction. You might think you're stepping through the source code at a nice high level and the computer's waiting for you, but that's not really what's happening. And like all abstractions, they leak. Here are a couple of ways in which you can get tripped up:

      • The source code map is wrong. Because you're not really stepping through the source code, but whatever it's been compiled to underneath, the debugger has to map that low level mess back up to the right lines in your source somehow. This is normally done by using a big ol' map that says thinks like "addresses 0x002a1fb4 to 0x002a1fbc correspond to line 45 of frobinicate.c". Unfortunately, if you recompile that source, the map probably won't make sense anymore, and if the debugger gets the wrong one, you can find yourself stepping through the "wrong" parts of code, like blank lines.
      • Stack overflows. Go and smash your call stack. Here's an easy way:

        void crash() { char foo[ 5 ]; sprintf( foo, "Let's smash the stack and cause mayhem!\n" ); } int main() { crash(); printf( "Come back from crash\n" ); }
        Compile that and step through it with your favourite debugger. I don't know exactly what will happen when the debugger exits the crash() function, but I'll be happy to bet a whole five jam tarts that it won't step into the call to printf in main.
      • Race condition ahead. Suppose your code has got a race condition in it. Trouble is, when you step through code in the debugger, you can get a section of code to run slowly enough that everything seems to work ... until you then run it outside the debugger and it all falls over in a mess.
      • The code's not running here. Supposing you've got what those of you who've battled with COM would call an out of process server. Well, you can't just step into the code, because the debugger isn't hooked to that process. You can make it step into it, but you have to help the debugger a bit. And what happens if the code's running on a totally different machine? You can set both boxes up for remote debugging, but at that point I'd start to wonder if it's really worth the hassle.

      So there we go, there's some ways that the debugger can kick you in the face. Harrumph. What alternatives are there out there? Here are two popular ones :

      • Log, log and thrice log. If you know an error has occurred, or some state may be invalid, log it. If you're about to step into some code which isn't extensively tested, log the entry and exit to it. There are plenty of logging utilities out there. log4j and log4net are popular solutions for Java and .NET respectively. My general solution for debugging some of my dodgy PHP code is to temporarily sprinkle it with echo statements that print out what I think's happening. You may see grizzled old timers like our Yorkshiremen above refer to this as printf debugging because in the olden days of C programming in Unix, this was the de-facto way of writing out some debugging information in a place you were likely to notice.
      • Use the source, Luke. If the debugger and logging won't help (and with embedded software that happens more likely than you think - where's a tiny box with a Z80, 16K of RAM and a two digit LCD display going to display your debugging messages?) there's only one thing for it - dive into the source code and trace through it methodically until you find the bug. Grab a friend and code review it. If this sounds like hard work - well that's because it is. But you can apply this technique even when you can use debuggers. Supposing you've got a silly off by one error but it only manifests itself on the production server. A code review might spot it in five seconds. Setting up the remote debugger to step into the code to work out the same thing might take half an hour setup, plus five seconds to find the bug.
      Now, I'm not saying don't use a debugger, ever. I'm not Linus. But understand what your debugger's doing underneath, and you'll do better than those that rely on it. ]]>
      Mon, 30 Jun 2008 11:40:21 +0100 http://ritchieswann.com/index.php?file=debuggers
      Some Mellotron stuff http://ritchieswann.com/index.php?file=tron

      Have a look at this site. It's a bunch of recordings from the infamous Mellotron. While I like a lot of older electromechanical keyboards (and I could write tons about them if several other people hadn't done so already), the 'Tron (as it's affectionately) known is one of the few bits of vintage gear I've never actually seen.

      For those not in the know, the Mellotron basically works like this : you press a key, it pulls a bit of tape with a pre-recorded sound. Just like a sampler, only with lots of pulleys and tape heads. And a hundred times heavier and impossible to rackmount.

      (Okay, Mellotron gurus - there's your challenge - make a 19" rack version. I dare you....)

      Anyway, the text around the various recording is well written too - how else could you describe Moog Taurus pedals as "loud, bastard loud and ...", well go and read the article.

      ]]>
      Tue, 17 Jun 2008 10:32:16 +0100 http://ritchieswann.com/index.php?file=tron
      Why buy the same record twice? http://ritchieswann.com/index.php?file=same_record_purchases

      (Sorry I've been a bit quiet on the blog front recently - I've got a queue of code stuff whose examples haven't been properly tested. When I get a spare evening....)

      I've just realised that in the past 18 years I have bought The Yes Album four times. In order, these were...

      1. Original issue CD. Lots of hiss and the fadeout in the last track is clipped. This one bit the dust when somebody dropped it on the floor and squashed it with a chair leg.
      2. Original LP with the full gatefold sleeve. Still got this but as my old record deck's sitting in the loft with a worn stylus it's not really an option.
      3. Mid nineties reissue CD. Think my flatmate ran off with this one.
      4. 2003 reissue CD. The best one yet, the keyboard sound particularly kicks some ass (something which I have to say their more famous keyboardist never managed to achieve). It's sitting in my car CD player right now.

      Have I been had? Or is it just bad luck? Come to think of it, how come I'm still listening to this nearly 40 years after it was recorded, and 20 after I first heard it? Maybe I'm getting stuck in my old ways.....

      ]]>
      Mon, 16 Jun 2008 10:05:41 +0100 http://ritchieswann.com/index.php?file=same_record_purchases
      Don't lie on your CV http://ritchieswann.com/index.php?file=cv_lying

      So we've all seen (or heard about) the latest series of "The Apprentice", and found that Lee "That's What I'm Talking 'Bout!" McQueen has got the job despite the fact his CV was full of spelling mistakes and incorrect dates.

      Don't fall for it. Unlike Lee, you haven't got the benefit of the interviewer knowing about your skills in buying alarm clocks in Morocco or selling thongs in advance. You'll be raked over the coals for it, and rightly so.

      If you find spelling hard, get a proof reader. If you think being creative with dates will help you, disabuse yourself of that notion.

      ]]>
      Thu, 12 Jun 2008 10:01:57 +0100 http://ritchieswann.com/index.php?file=cv_lying
      Developers and abbreviations http://ritchieswann.com/index.php?file=more_spelling_mistakes

      A few weeks back I was ranting about developers and spelling mistakes. And ages ago I was whinging about text speak (which I still don't understand.)

      So you can imagine what I feel about code that combines the two together like this :
      FrobnicatorManager frobMgr = FrobnicatorFactory.AllocateManager();

      I'll accept this code on precisely one condition - that any variable that references a FrobnicatorManager in the entire source tree is totally consistently abbreviated like this. However, I've never ever seen a code base where this is actually the case.

      Spell things out. If it makes your code too long, it probably whiffs a bit.

      ]]>
      Mon, 12 May 2008 12:31:56 +0100 http://ritchieswann.com/index.php?file=more_spelling_mistakes
      On Reactos http://ritchieswann.com/index.php?file=reactos

      I've recently stumbled across Reactos and I've got real enthusiasm for it.

      Basically it's an open source reimplementation of Windows. More specifically, it's a reimplementation primarily of the kernel, with some common shell tools (Explorer, cmd, that sort of thing), leaving most of the other userland stuff to Wine.

      "Yeah right," I can hear everyone saying, "Any old idiot can start an over-ambitious open source project - it'll just go pear shaped when they start debugging in earnest." But it does seem to have got off the ground, covered a lot of the kernel and runs some software. It's still alpha grade - you can make it crash without too much determination and it doesn't recognise my old 3C900 network card. But it's getting there.

      In fact, it's worth mentioning how the odds are stacked against Reactos' favour. There's no public source for the Windows NT kernel - the internal structures have to be worked out the hard way by clean room engineering. And there's always the threat of Microsoft getting the hump and accusing the team of ripping off their code. And at least Linus had a bucketload of userland software from GNU he could test against, with the source for it widely available - the Reactos team had to implement the shell as well as the kernel completely from scratch.

      "So what", you say, "If you want a free OS, why don't you install Linux or BSD?" Here's why:

      • Linux sucks on the desktop : Yes, we've come a long way since twm was the best window manager to use, and Ubuntu has come on leaps and bounds with making a user friendly desktop for Linux. But it's not as good a UI as Windows XP, and you can't buy OSX off the shelf to run on commodity PC hardware. I don't think it's any big surprise that most of my Linux work is on background server side processing stuff, and my main box doesn't even have a monitor or keyboard plugged in any more.
      • More people know Windows than Linux. Most people who use a PC at work use Windows and Office. Yeah, I know you're a trendy Rails startup and you use FreeBSD all the time, but you're not most people.
      • Linux is forever playing catchup with Windows device drivers. One of the biggest problems I've faced over the years when upgrading bits of hardware is "Will it work under Linux?". Remember all the palava about getting Diamond video cards to run under XFree86? We've got better since then, and some manufacturers even provide Linux drivers now, but the fact remains that even if the driver exists, you might have to search through a number of HOWTOs and recompile your kernel to get it working. It's certainly not as easy as popping the CD from the manufacturer in your PC and hitting "Install".

      So, Reactos has got some momentum. The trouble is, I don't think it's got enough momentum. Currently, it's relying on donations. That's all well and good, but to get all the nitty gritty of testing, documentation and bugfixing sorted out, you really need full time staff to do this.

      Let's take that 3C900 issue I mentioned above. That's a deal breaker. All modern Linux distros recognise the card out of the box, and I'd be flabbergasted if XP didn't. If I have to do any sort of hacking to get drivers to work in Reactos, it's not as good as Linux.

      While doing a clean room reverse engineering of Windows is an impressive achievement of itself, the big challenge I think is to get it to a state where device drivers "just work". That's going to require a lot of hardware, and a lot of testing. Microsoft can spend their way out of that problem, but Reactos can't - they just have to hope people volunteer to test hardware and write or debug drivers.

      Reactos really needs a big sponsor to take it onboard and let it fly. If it can get to the stage where it's a compelling replacement for XP, and runs most if not all hardware as well as that, it could be a winner. So here's hoping.

      ]]>
      Tue, 29 Apr 2008 11:35:06 +0100 http://ritchieswann.com/index.php?file=reactos
      On Open Source http://ritchieswann.com/index.php?file=open_source

      I'm a bit of fan of Open Source software. I'm sitting here typing this in vi, launched from bash on my Linux box remotely accessed via PuTTY. Later on I'll use a GNU ftp client to upload it to another Linux box, where everybody can connect to it via Firefox, which will run a PHP script to display the output to everyone.

      And at some point I've really got to put some proper source control on the blog code before I make a silly mistake.

      Phew. That's a lot of open source. (Okay, I missed out one thing - the PC I'm connecting from is running Windows XP. Show me a window manager and GUI that equals this (and doesn't cost an arm and a leg ) and I'll happily shut up. There's your challenge for today).

      Anyway, I noticed that really good open source software (which includes pretty much everything I've mentioned above) follows two patterns :

      1. The software was written, at least initially on a college campus. Stand up Linus, Alan and rms. Oh, and Simon. Some public money propped up the development effort (or do you think rms generates his own electricity from hamster wheels? Well I suppose it's possible).
      2. The software was sponsored by a large organisation that invested serious amounts of time and money on it. Take a bow Transmeta (Linux), Sun (OpenOffice), Novell (Linux, Mono), IBM (Eclipse) and Google (Audacity, Linux) - and those are just off the top of my head.

      Notice a pattern? These projects had serious time and money thrown at them. People do get paid for writing open source (or at least the kind that gets really popular and used by a lot of people). There's very little chance that your app is going to be eaten alive by a seventeen year old pizza and cola fan who doesn't care about getting any money. You can still get paid for writing software if you want.

      ]]>
      Fri, 25 Apr 2008 11:09:49 +0100 http://ritchieswann.com/index.php?file=open_source
      Speling Miztakez http://ritchieswann.com/index.php?file=code_spelling_mistakes

      What is it with developers and spelling mistakes?

      You know if you come across code like this you're going to be in for a rough old ride:
      // Make sure the distnace is set up properly, otherwise we'll get a
      // race condiiton when the Frobnicator gets refrshed
      ...

      Yup, it's the curse of the spelling mistakes in code. If you see code with spelling mistakes, it means it hasn't been properly reviewed and debugged yet. So there's probably a whopping bug stuck in the middle of it. In fact, if a comment talks about race conditions and mis-spells the term, it's almost guaranteed you're going to have less hair by the end of your debugging session than the start.

      Okay, we're not all perfect. You've probably read that the human brain can raed wodrs in any oredr as lnog as the frsit and lsat are the smae way ruond., which is what makes transpositions like this easy to slip by. And when I see spelling errors, 99% of the time it's two letters in the middle swapped around by accident because the developer was so busy bashing out code so they could mark a feature as "complete" and spend the rest of the day munching on doughnuts.

      (mmmm....doughnuts)

      Anyway, we're only human. We make mistakes. The problem is when they don't get fixed. A second pair of eyes can generally spot these problems (this is one of several reasons why I like code reviews), but some developers just don't seem to give a monkeys and write things like "linkedDocuemnt" all over the place, probably while they were sacrificing goats at the temples of cut-'n'-paste and Intellisense.

      Stop it. Now. I can fix my spelling mistakes. (The first draft this post had "doughnuts" spelled as "dougnuts"). So can you.

      ]]>
      Tue, 22 Apr 2008 11:15:33 +0100 http://ritchieswann.com/index.php?file=code_spelling_mistakes
      Hacking Attempts http://ritchieswann.com/index.php?file=hacking

      It seems some people are firing junk URLs at this site to try and crack it or post spam in comments. That won't work - the file part of a GET request isn't a real URL, and a request it doesn't recognise gets ignored. You'll have to try harder than that. <raspberry>phphphphpphph</raspberry>

      ]]>
      Sun, 20 Apr 2008 21:36:11 +0100 http://ritchieswann.com/index.php?file=hacking
      Cobol On Cogs http://ritchieswann.com/index.php?file=cobol_on_cogs

      This is simply brillant:

      Cobol On Cogs

      Somebody's clearly spent some nice time and effort coming up with a very convincing emulation of a green screen terminal in JavaScript. Shame you can't switch from green to orange, which I still see on POS terminals when I'm shopping every now and again.

      Next week : Spectrum on Stilts?

      ]]>
      Fri, 18 Apr 2008 09:59:11 +0100 http://ritchieswann.com/index.php?file=cobol_on_cogs
      It's a busy day for blogs http://ritchieswann.com/index.php?file=meta_april_08

      This morning I fired up RSS Bandit and for the first time in a very long time, the big four blogs on my list (that I'd recommend to any software developer worth their salt) have something worth reading. Hmm, busy news day I guess.

      Anyway, I wonder if I'm the only person around here who's wondering if the already infamous stackoverflow.com is maybe just a little bit overhyped?

      We'll see. Maybe I'm completely wrong and I should hire out somebody to make the audio book version of this site. My mate's just had his sat-nav upgraded so the voice overs are all John Cleese - wonder if he'll do my blog for a few quid extra?

      Update : When I said these blogs have something worth reading, I meant that they all had a good article at the same time on the same day. I wasn't saying they had something worth reading on them each for the first time in ages. You can make up your own mind about that, y'know.

      ]]>
      Thu, 17 Apr 2008 15:18:14 +0100 http://ritchieswann.com/index.php?file=meta_april_08
      Why can't you enumerate events in WinForms? http://ritchieswann.com/index.php?file=dotnet_events

      This ought to be simple. I don't mind using WinForms for little noddy apps. There's one here on this very blog, after all. But there's something that's really bugging me, and I'm surprised I can't find an answer.

      To fill you in, you have various controls in WinForms. Y'know, list boxes, combo boxes, list views, your basic archetypical Windows 95 application stuff. The problem with these is that events have a tendency to cascade when you don't want to. For example:

      ...
      cmbCustomers.SelectedIndex = 0;
      ...
      private void cmbCustomers_SelectedIndexChanged( object sender, EventArgs e )
      {
        ...
      }

      Okay, so far so good. But there's a small, but subtle problem. That SelectedIndexChanged event is going to get fired under two scenarios:

      • The user clicks on a different item in the combo box
      • My code sets a different index.

      To cut a very long story short, I want to be able to tell the difference between them. But I can't. However, what I could do is something along the lines of....

      ...
      TurnOffEventsForAMinute( cmbCustomers );
      cmbCustomers.SelectedIndex = 0;
      TurnEventsBackOn( cmbCustomers );

      Now if I can implement those two functions TurnOffEventsForAMinute and TurnEventsBackOn, I'm laughing. It'll work for any combo box on any events. Reusability-tastic! Right - let's have a think about how we might implement these.

      Okay, if it's going to work with any combo box, it's going to need to know about any event handlers, even none at all, and it won't know which ones are set until runtime. Shouldn't necessarily be a problem, right? All you have to do is get a list of events and turn them all off or on, depending on which function you're implementing.

      Well, it turns out you can't enumerate through handlers on an event. At all. Actually, that's not strictly true - you can have a look at the Component.EventList property using Reflector and you'll see it's just a C style linked list of delegates. They're all private, but with a "nice" bit of reflection to access private members, you can force it through.

      Ummm, no thanks. Maybe as a "I can do this, it's so cool" blog post, but not in production code. It's like saying I can cook a sausage by wiring up two ends of a 240V mains supply to it. It works, but it's the wrong way of doing it. You shouldn't party on implementation details otherwise you'll get bitten when they change. And Raymond Chen will be blogging about you in three years' time.

      Anyway, looks like I'm SOL on enumerating event handlers in WinForms. Swizz. Maybe I should just go over to web apps full time....

      ]]>
      Thu, 17 Apr 2008 12:39:45 +0100 http://ritchieswann.com/index.php?file=dotnet_events
      Dubbed for television http://ritchieswann.com/index.php?file=dubbed_tv

      I've recently realised I have never actually seen Live And Let Die in its original, unedited form - only ever from television broadcasts of it, which inevitably leave out certain bits, like:

      • The secret agent in New Orleans (right at the beginning) getting fatally stabbed in the leg. (What's wrong with that?)
      • The woman having the flying lesson exclaiming "Holy ****" as Bond tries to fit a light aircraft through hanger doors wide enough to maybe take a Segway if you're lucky.
      • And most significantly, half of J W Pepper's dialogue.
        J W Pepper
        "Golly gosh darn heck it's that chuffin' secret agent!"

      Still, it's all a bit academic - the scarecrows scared the bejingles out of me when I was nine years old you know...

      ]]>
      Mon, 14 Apr 2008 22:20:26 +0100 http://ritchieswann.com/index.php?file=dubbed_tv
      Aspect oriented programming http://ritchieswann.com/index.php?file=aop

      Last week I was talking about how less is more and you should try and get more mileage out of your source code if possible.

      One popular paradigm bouncing around at the moment is Aspect Oriented Programming. In a nutshell, it allows you to "hide off" common bits of functionality without them cluttering your source code.

      Confused? Okay, let's take an example. Let's say I've got a bunch of functions like this:
      void foo()
      {
      ...
      }
      void bar()
      {
      ...
      }
      Supposing I put this code on a server somewhere, and an end user says "Your software sucks! It's too dang slow!" Well, it runs perfectly quickly on my machine, but that excuse doesn't tend to fly too well with users for some reason. I'm not sure which function out of foo() and bar() is causing the slowdown, so I'll put some logging in:
      void foo()
      {
      LogEntry( "foo" );
      ...
      LogExit( "foo" );
      }

      void bar()
      {
      LogEntry( "bar" );
      ...
      LogExit( "bar" );
      }

      Well that's all good stuff. I can now capture some logging times and see that bar executes databases queries in a loop, which is fine and dandy for my test system with 5 widgets, but for some totally bizarre reason just does not scale for the end user's system with 5,000. Hmmm. Oh well.

      Now, let's stop talking about contrived examples for a minute, nice as they are. In practice, I'm not going to have an app with just two functions in it, there's going to be many more. Who's going to retrofit all that logging code? Okay, that's my job. I get it. I don't know about you but, unlike computers, I'm no good at doing boring repetitive stuff. I make mistakes. It would be nice to just decorate all the functions in some way, so they log themselves on entry, and on exit, without having to remember to call the logging utility functions all the time.

      And that, in a nutshell, is what Aspect Oriented Programming is about. In other words, I'm trying to get more out of less code again.

      Now, how you implement that in the real world is a bit more tricky. Here are a couple of approaches I've used so far :

      • Use reflection to "decorate" functions in a certain way. This works well to some extent, but it means calling the function is a bit more tricky. You could create a "helper" function that takes a function as input, interrogates it for any "aspect" attributes, calls them, then calls the function passed in. I'm not sure you actually get a decent trade off of code readability, and reflection is always slower than calling a method directly. If you've had more success than me going down this route, let me know.
      • Writing a preprocessor that takes the source file, injects the extra code, then passes the output to the main compiler. This is all well and good, but can sting out at debugging time when the code you're running is not quite the same as the code you initially wrote. It's #define hell all over again.
      • Taking a compiled unit of code and "tweaking" it. This is really a variation on the above, except the tweaking's done after instead of before compilation. The System.Reflection.Emit namespace in .NET should make this possible.

      All the same, AOP is an interesting area to research. If you can get a decent implementation sorted, as you should end up getting more out of less source code. Let me know if you've got any useful insights.

      ]]>
      Mon, 14 Apr 2008 20:21:32 +0100 http://ritchieswann.com/index.php?file=aop
      Do you still run as an administrator? http://ritchieswann.com/index.php?file=non_admin

      The other day I was reading a code sample I thought I'd try. I typed it up, compiled it, and it blew up in my face. That was a bit unexpected.

      Well it turns out it was because of this :
      StreamWriter writer = new StreamWriter( @"C:\test.txt" );

      Well that's not going to work because my main account doesn't have rights to party on the root drive like it's 1999. It doesn't need to, and it's not going to. If I can scribble junk on the root of my main drive, who's to say any amount of malware, spyware and virii can do the same? (Of course, I usually read my email via pine as it makes clicking on dancing bunnies positively user unfriendly, so I don't hear about your average virus until it appears on the news somewhere).

      Most Microsoft software works quite merrily as non-admin these days. All the Windows control panel apps play nicely and prompt me for an administator password if I want to do something dangeous. But not everything does. My ancient laptop's PCMCIA wireless card can't seem to even breathe unless it's launched as admin. So I have to keep typing the administrator password the first time I want to look at a website.

      Grr.

      If you're still running as an administrator, stop it. Now. There's even a whole blog about why it's a bad idea. Get with the program.

      ]]>
      Thu, 10 Apr 2008 14:09:15 +0100 http://ritchieswann.com/index.php?file=non_admin
      Make Four http://ritchieswann.com/index.php?file=makefour

      This is a well known counter game that you've probably heard of. You play Player 1 (red) and the computer plays Player 2 (blue). Each player takes turns to drop their counters into one of seven slots.

      A row of four counters of the same colour wins the game, whether they are vertical, horizontal, or diagonal. If the board is filled, the game is a draw.

      Make Four (Linux + Mono) Make Four (Windows)
      Make Four on Linux Make Four on Windows

      The game was written in C# under Mono, but should also work under Windows using the .NET Framework SDK.

      Download Make Four for Unix + Mono

      Download Make Four for Windows

      PS: Sorry about the awful graphic counters. I had some better ones but they were copyright. I will try and make some better ones soon.

      ]]>
      Wed, 09 Apr 2008 19:46:45 +0100 http://ritchieswann.com/index.php?file=makefour
      Gollum Comments http://ritchieswann.com/index.php?file=gollum_comments

      Have you ever seen code like this?

      // We must set the frobnicator here otherwise our doohicky will not
      // correctly be initialized. We get the values respective to the foobar
      void InitializeFrobnicator( const foobar& myFooBar )
      {
      ...
      }

      What's with all this we and our business? Are you trying to talk like Gollum or something? Who's the "we" in this case? You and the computer? You and your imaginary friend who does your acceptance testing?

      Anybody know the riddle to this one?

      ]]>
      Wed, 09 Apr 2008 13:39:44 +0100 http://ritchieswann.com/index.php?file=gollum_comments
      Comments http://ritchieswann.com/index.php?file=new_comments

      Right, I've implemented comments. They should be implemented on all articles from now on. I've used an anti-spam method I've used on some other sites which stops simple POST phishing bots, which seems to be the main culprit. We'll see how it goes.

      While I'm here, here's some ruby code I wrote for you to critique. Bear with me, I'm seriously wet behind the ears on this language..... #!/usr/local/bin/ruby
      require 'socket'
      server = TCPServer.new(8081)
      loop do socket = server.accept
      all = Array.new
      begin data = socket.gets
      all.push data
      end while data.chop.length > 0
      all.each{ |line| socket.puts line }
      socket.close
      end
      Run this and fire your browser at port 8081 and it'll dump out everything the browser sent, the most interesting being the user agent. This is what allows you to tell the difference between IE and Firefox (at a crude level).
      It's also an attempt to write a reasonably useful app in as few lines of code as possible. But I'm sure you can do better. C'mon - critique away....

      ]]>
      Tue, 08 Apr 2008 20:53:02 +0100 http://ritchieswann.com/index.php?file=new_comments
      Less is more http://ritchieswann.com/index.php?file=less_is_more

      Today I thought I'd come up with a contrived analogy because it's always interesting reading. Let's compare two guitarists who were popular in the sixties : Steve Cropper to Alvin Lee. If you're not sure who either of these are, go and have a look at the links and then come back here.

      Okay. From that we can conclude several things:

      • It's harder for a beginning guitarist to play fast than slow or sparse.
      • Alvin Lee plays waaaaay more notes per second than Steve Cropper.
      • Most people (certainly most music critics or reviewers - yes messrs Wilson and Alroy, I'm thinking of you) think that out of the two, Steve Cropper is the better player.
      • A principal reason for this is Steve Cropper plays less notes per second than Alvin Lee.
      (Of course, somebody somewhere is now bashing away on their keyboard composing a nice flamefest about how I know nothing about music and how dare I slag off their favourite guitar player / band / distant relative. It's a friggin' analogy - just bear with me....)

      It's the same with software. (Of course, now everybody is bashing away on their keyboard saying "he's trying to make an analogy with software and guitar players - jeeeeeeez what is this guy smokin'?). You do not get points with the customer for having more and more fancy code. In fact, as a developer, you should always strive to make your codebase as small as you can without sacrificing functionality.

      Why's this?

      • A smaller code base is more readable - there's less stuff you have to remember. This is one reason why things like EJB give me the heebie geebies - it doesn't seem to be possible to do a simple insert without wrapping up with loads of bloatware.
      • A smaller code base has less places for bugs to hide. This is sort of self explanatory - if there are less places for you to make a mistake, it stands to reason that it's less likely that you will.
      • A smaller code base is probably easier to maintain. If you define your frobnicator in one place as opposed to fifteen, you'll have less work to do when you realise you got the definition of it wrong.

      If you want to improve your development skills, keep the code size down!

      But Ritchie, I can't get the code size down anymore because my language doesn't support it - cut and pasting is the less of all evils!

      Aha, if you're in this boat and want to improve, you're going to have to discover the marvels of compilers and code generators. More of that in a later post....

      ]]>
      Tue, 08 Apr 2008 12:06:19 +0100 http://ritchieswann.com/index.php?file=less_is_more
      Why I Like Bug Reports http://ritchieswann.com/index.php?file=bug_reports

      This morning, I decided to test the RSS feed in something more substantial than just looking at the XML and thinking "eh, that looks okay". So I fired up RSS Bandit and attempted to add this site to it.

      Ten minutes later, a bugfixed version of the blog code was being uploaded...

      Now, I have to say that I'm the only person on this planet at the moment whose time was worth doing that. I knew the RSS feed really hadn't been tested and I just fancied spending some time last night making cheese on toast instead of downloading an RSS aggregator and doing some proper testing.
      But for the rest of the universe, that's not the case. If you see a nice little "RSS" icon, you assume it'll work. Why wouldn't you? And if you discover it doesn't work, you think anything from "oh dear" to something I couldn't possibly write before the watershed.

      It's the same with most software, I think. Most users are simply using software to do their job. If bugs crop up, they might think it was their silly mistake, not the developers. If, heaven forbid, it's a hard to reproducing crashing bug, they might just go grab another cup of coffee and restart the app. Hands up everyone who's had Word crashing? Yup, lots of people. Now hands up everyone who's written good repro steps for every time that's happened so they can give enough information for the bug to be fixed? Hmmm .... not so many people now.

      You've got to get testers on your side. This should be obvious to your own testers (umm, you do have testers on your team, right?), but it applies equally to beta testers. They have to be motivated to file as many bug reports as possible, so we've got a chance to make software better.

      At the end of the day though, sometimes the only person who'll improve the quality of your code is yourself.

      ]]>
      Mon, 07 Apr 2008 13:49:08 +0100 http://ritchieswann.com/index.php?file=bug_reports
      Separated at Birth? http://ritchieswann.com/index.php?file=separated_at_birth

      On the left, the knife welding moog twiddling Hammond destroying maniac of prog, Mr Keith Emerson.

      On the right, the only man who writes his own shopping list as ( cons bread ( cons eggs ( cons milk butter ) ) ), Mr Paul Graham.

      Keith Emerson Paul Graham and his new Lisp mainframe

      Well I've never seen them in the same room...

      ]]>
      Sat, 05 Apr 2008 21:49:10 +0100 http://ritchieswann.com/index.php?file=separated_at_birth
      More supermarket observations http://ritchieswann.com/index.php?file=packaging

      It seems to be de rigeur these days for anybody immediately at the front of a checkout in Tesco to be asked "Would you like any help with your packaging?"

      This is a serious moral dilemma. If I say "no", then I'm going to look like a bit of an idiot desparately trying to open the plastic bags (which I've never been able to really do successfully) while the shopping piles up, but if I say "yes", I'm going to admit I'm cack handed at opening small pieces of plastic to put bags of bread and boxes of Sugar Puffs in.

      Sometimes, you've just got to pick your own battles.

      ]]>
      Fri, 04 Apr 2008 21:58:00 +0100 http://ritchieswann.com/index.php?file=packaging
      Why You Need Automated Unit Testing http://ritchieswann.com/index.php?file=unit_testing

      I'm a fan of (automated) unit testing, don't you know.

      Meet Mutt. He likes to bang out code like there's no tomorrow. "This won't take a minute, I'll just have to add the frobnicator - no worries." So off he goes bashing away at his ancient IBM Model M (remember those?) churning out class after class, function after function, lambda after lambda (hmm, does the bad guy in a contrived example actually use lambdas? Never mind.)

      Now meet Jeff. (No, not that one). He's been bitten one time too many time by nasty bugs, though this time around he's going to write some unit tests. He write a test, puts a bit of code around it, then tests it. It works. He repeats the same thing. It works. This goes on for a few more times and lo and behold, his code's done and he's confident it works.

      Meanwhile, let's go back to Mutt's desk. "How's it going, Mutt?"

      Mutt clears his mouth of pizza and jolt cola to reply. "Oh don't ask. It was all going so well, I even compiled halfway though to shake out the syntax errors. But I've run it and it's blown up in my face."

      "Where's it blown up, Mutt?"

      "All over the place. I fixed the wiginator code over here, but that tripped up the frobnobnicator framework generator, which I then had to refactor to use a hash table instead of a vector, then ... ooh it's all gone Pete Tong."

      So, six hours after Jeff's gone home for the day, Mutt's sitting there tearing his hair out. It doesn't have to be this way you know.

      What's so great about unit testing. Well, basically, when you've finished a bit of code, you've got confidence that it works. You don't build up piles and piles of code, test it one way then forget about it. You let the computer do some of the leg work for you. Over time, it can make a real difference.

      Now, let's take some questions from the floor....

      Unit testing's going to take too long. It's going to involve more code and take more time. My pointy haired boss will never green light that!

      Aah, that's a shame. Hasn't he heard of "short term pain for long term gain"? Or did he nip to the loo or doze off and think about golf while Steve McConnell was saying "If you don't have time to do the job right, where will you find the time to do it over?" Especially when "doing it over" takes five times as long.

      Although unit testing is no silver bullet, from my experience of projects that have some code unit testing, and some code that isn't, the quantity of defects found in the code without tests outshone that of the code that did by a factor of 20. Hmmm, nice return on investment there. Yeah, you gotta spend a bit more time writing some test code. But you'll then be spending less time thrashing around in the debugger trying to fix that bug you introduced when fixing the other bug last week. Your call.

      Unit testing's too hard. I'm going to have to write tons of scaffolding code

      While frameworks such as NUnit make unit testing much easier, you can do it the old fashioned way with a straightforward executable. Let's say you've got a function frobnicate and when you pass in 7, you expect to get out "7 frobnicators, please!". You could do something like this :

      test()
      {
        string result = frobnicate( 7 );
        if ( result != "7 frobnicators, please!" ) {
          perror( "Frobinicator failed!" );
        }
      }
      
      
      You could probably guess all that, I just wanted an execuse to write gibberish like "frobnicate" several times.

      That's brillant! I'll go and write tests after all my code now....

      Woooah, not so fast, big boy. You can do that, but I reckon you'll get better mileage if you write the test first.

      Why's that? Well, the act of writing the test makes you really think about what your code is going to do. It can act as a sanity check that you've got the requirements correct before delving into code. And you'll have a good idea that you're done not just because it compiles and seems to run, but because the test passes.

      How do I test back end server code called by GUIs?

      Just replace the GUI code with some test code. Simple, really.

      How do I test external database / server / hardware in my tests?

      This is where it gets a little more tricky, but you can work around it by using a mock object that simulates the boundary in which you're working. I once wrote a mock FTP server that randomly hung or dropped "packets" on the floor, to test various error conditions.

      I've got all this code already, I can't just go bolting on unit tests to it!

      This is one of the biggest obstacles to adopting unit tests, as it's something that's really ideally done up front. But you're still fixing bugs and writing new features, right? Start by writing tests for the new code, and plumb the rest in gradually if you can.

      Even in the depths of spaghetti code, there has to be a user interface somewhere, or a database or files that are used for communication. See if you can drop out one part of your code and swap it for a test.

      Or, as an alternative, if your app generates files or data, create a set of "control" data that your app should produce. Run the app, and compare the data. That'll at least automatically test something.

      Well that's great! I'm looking forward to having bug free code!

      Ummm, right. Sorry to break this to you, but you're going to be disappointed if you think that. You see, unit testing can't do everything. It won't check if your design's wrong. It won't check if your requirements are wrong. It won't tell you that even though the customer absolutely insisted in their own blood that they didn't need the pasta trimmer, it turns out they do 'cause dopey old Fred forgot he needed it. All it really does it tell you that your code works the way you think it should work. You still need good old fashioned testers and QA.

      Well there's some ideas on unit testing for you. If you want to find out more, you could do worse than look at the Pragmatic Programmer series of books, which go into how to tackle unit testing in more depth. Or drop me a line.

      ]]>
      Tue, 01 Apr 2008 22:27:00 +0100 http://ritchieswann.com/index.php?file=unit_testing
      Real ale drinkers http://ritchieswann.com/index.php?file=real_ale

      The present Mrs Swann has taken mild objection to describing myself as a "real ale drinker" on the basis that she knows if someone blindfolded me I wouldn't be able to tell the difference between a pint of real ale, and a pint of lager with horse poo floating in it. Not that she thinks there is much difference...

      Must go, we've got a bad case of cat on keyboard.

      ]]>
      Tue, 25 Mar 2008 23:24:00 +0000 http://ritchieswann.com/index.php?file=real_ale
      Never insult your audience http://ritchieswann.com/index.php?file=audience

      There's not too many Ritchie's around. (Well I don't think so). When I was younger, I was quite a fan of this one. A good Ritchie to have bouncing around (and probably a lot more interesting to watch than this one).

      Until November 9th, 1993.

      Why's that?

      That's the day that me and my mate caught a train from Southampton to Birmingham (I think they were doing cheap discounts for student rail travel) to see Deep Purple at a gig. There are two things that stick in my mind from that gig. The first is being stuck all night on Birmingham New Street platform in the freezing cold, but I can't really rant about that. (Actually, stuff that, I can. I am now. Ummm, right, I'll stop.)
      The second is that this Ritchie threw what I can only describe as a hissy fit and didn't go on stage for half of the first number. I think my mate described him as a four letter word I can't repeat here because this is supposed to be family viewing.

      Right, here's my top tip for musicians. If you're pissed off with your group, leave the group. If you don't like what the other guys are doing, quit. If you run the band, sack 'em. But whatever you do, you should never blow out a gig and take your personal problems out on stage. It pisses the audience off, especially if they'd have to pay for it!

      ]]>
      Tue, 25 Mar 2008 22:32:00 +0000 http://ritchieswann.com/index.php?file=audience
      Code Reviews http://ritchieswann.com/index.php?file=code_reviews

      "Right then, Ted. It's time for a code review. Good grief, Bob, look at the way he's done this!"

      "That's awful, Bob. The way he's laid that spacing out looks horrible on this fanfold paper. And why's he called that variable current? Current what? Current bun?"

      "Umm, it means the current counter inside that loop. If you look at the code, it's really self explanatory."

      "Self explanatory, schelf explanatory. You should name that variable currentPositionLoopPageIndicatorCounter. Then there'll be no confusion!"

      "Wait a minute, Bob, that won't fit on our dot matrix printer, d'ya think we could abbreviate it a bit?

      Ahem....
      Actually, I'm a big fan of code reviews, when you do them correctly. The most important point is that the reviewee does most of the talking.

      A while back, I came across the Tech Support Teddy Bear. It's a great idea. Before you go to the sysadmin with a tech support problem, you have to describe your problem to the teddy first. Now it seems like the teddy's a smart chap, cause he can answer most of the problems.

      Why's that? Simple - the act of talking through your problem forces you to go through your entire thought process in a very methodical manner. When you say your problem out loud, the solution can leap out at you. A handy side effect of this is that nobody minds discovering their own problem, but everybody hates somebody else discovering the problem for them. So that's developer morale ticked up a notch just for that.

      Code reviews don't need to be formal. In fact, they never should be. Just grab somebody nearby who's free and run through things for a second opinion. Obviously the last remaining bugfix before a release needs to be run through with more detail (ever found you fix a sev-2 bug then introduce a sev-1 as a byproduct?) than the first cut of a new feature, but you shouldn't trample your reviewee as a byproduct. If they're relatively inexperienced, guide them a long with some questions. "What happens when you do this?" .... "Could you get a race condition here?" "Does this work in Bulgarian Windows on the third Friday of each month when the moon is in the ...." - actually, scratch that one.

      ]]>
      Tue, 25 Mar 2008 22:06:00 +0000 http://ritchieswann.com/index.php?file=code_reviews
      Pig Latin Generator http://ritchieswann.com/index.php?file=pigl

      This is a fairly straightforward Pig Latin generator for UN*X style shell scripts. It takes the standard input and applies the following transformations :

      • All alphabetic text has the first letter moved to the end
      • If the first letter began with a vowel, also appends "way"
      • Otherwise appends "ay"
      • All non-alphabetic characters are unaffected
      • The easiest way to use this is to just start typing and see your text being converted to Pig Latin on the next line.

        Alternatively, you can run the generator through a series of UN*X shell commands, which is what I like to use it for. The simplest example is : cat myfile.txt | pigl

        You can download the source here

        ]]> Tue, 03 Apr 2007 12:00:00 +0100 http://ritchieswann.com/index.php?file=pigl Text Messages http://ritchieswann.com/index.php?file=text_messages

        Text messages. They're a wonderful social invention. Suddenly you can "spod on the go" as it were. (Yes I know you fancy lot with PDAs have been spodding in the pub since 1996 - good for you).

        Now, it has to be said that the user interface for these things is not the best in the world, being as each "key" overloads onto three or four letters. It's like one of those prototype "chord" keyboards that were popular amongst computer scientists in the eighties.

        Anyway, for this reason, some people think it's okay to leave out letters and start talking as if every word is a Unix shell command. "Elo m8 do u fncy a grep tnite?" Or something like that.

        Anyway, the point I was trying to make is - don't try sending this sort of stuff to me because I can't understand a bloody word you're saying!

        Yes, I don't understand kids anymore. So there.

        ]]>
        Sat, 18 Sep 2004 12:00:00 +0100 http://ritchieswann.com/index.php?file=text_messages
        Toy Grabbing Machines http://ritchieswann.com/index.php?file=toy_machines

        I've got no idea what their official name is, but you're bound to have seen them, even if you live on the moon. They're the sort of machine where you put some money in, move a mechanical grabbing arm along one direction, then along another, at which point it briefly touches a cuddly toy, grabs some thin air and then returns to its starting position whereupon it lets go of the aforementioned thin air and drops it into somewhere where you can reach it.

        Now this is quite sneaky. I reckon it's physically impossible to win anything on these machines, because the weight exterted on the arm is so much less than if you were holding it. Which, presumeably is part of its appeal - it looks like you can win but in fact you can't. The best strategy I can think of is to stick a pile of cash into the machine and use each go to nudge one of the toys over to the starting point where it will fall down to the bottom of the machine where you can get it. I suspect, however, that this method probably involves sticking more into the machine than the money you'd spend buying the damn thing at a shop in the first place. Again, part of its appeal for owners.

        Has anybody ever seen anyone actually win something from these machines? Nothing less than videoed proof will do for me.

        ]]>
        Sun, 06 Jun 2004 12:00:00 +0100 http://ritchieswann.com/index.php?file=toy_machines
        Petrol Vouchers http://ritchieswann.com/index.php?file=petrol_vouchers

        For those of you who are fed up paying three weeks' wages for a tank of petrol, you can get money off vouchers if you do your regular shopping at Sainsburys. (I presume they do this at other supermarkets, it's just Sainsburys happens to be the nearest to me, so there).

        Now, these things used to be small coloured bits of paper that were just slightly larger than a credit or business card, so they wouldn't fit in your wallet without getting scuffed at the sides. And more importantly, there was a big "VALID UNTIL" date on it where the petrol discount ran out. This is very useful for people like me who put these things in their wallet, and promptly forget about them for six months.)

        Nowadays, however, the petrol vouchers are no more and you just get the petrol discout as a small bit at the bottom of your receipt. I reckon this is a way of stopping people getting discounted petrol. For a start the "VALID UNTIL" date isn't on there, just the date you got the receipt, in small fading print. So you have to do some sums before working out whether or not you can get discounted petrol. More importantly, receipts from supermarkets are incredibly easy to lose. I imagine they fall down some wormhole in the space/time continum somewhere until they turn up in the least expected places. Like the airing cupboard.

        Anyway, chances are that if I'm filling up I'll have probably forgotten the shrivelled remains of the petrol voucher, so that means I'll be paying over the odds just to get into work everyday. Bastards.

        Why can't we just get tokens?

        ]]>
        Sat, 08 May 2004 12:00:00 +0100 http://ritchieswann.com/index.php?file=petrol_vouchers
        Ritchie on Ritchie http://ritchieswann.com/index.php?file=about_me

        What's this all about, then?

        This site contains the thoughts and miscellaneous rants of Ritchie Swann, a thirtysomething software developer, musician, family man and real ale drinker. Those of you tuned in to the trendy lingo of today could describe it as a blog.

        Some of what I say may be cynical, some of it may be amusing, hopefully none of it will be boring. (If it is, let me know and I'll stick a joke in the middle of a paragraph - that'll liven it up a bit...)

        What blog software do you use?

        I've written my own blog software in php. If you really really want the source, drop me a line, though it's probably infested with bugs that don't affect me - that's internal software for ya ;-)

        There's nowhere for comments!

        Yeah, sorry about that, I haven't tested them enough to ensure they're spam free. Maybe one day...

        ]]>
        Wed, 16 May 2001 12:00:00 +0100 http://ritchieswann.com/index.php?file=about_me