Tuesday, July 15, 2008

Brian Sullivan tagged me with the latest ongoing meme. I’m really sort of excited because I’ve missed out on all the other memes going around. Jeff Atwood probably wouldn’t even consider me a real geek because of that. (I haven’t updated a Wikipedia page either! Gasp!)

How old were you when you started programming?

I didn’t write my first “Hello World” until I was 18 in COMP 170. I created my first personal website when I was 15 I think, but my primary tools were Netscape Composer and Paint Shop Pro. :-) I think I had figured out by that point some very basic Javascript, but I really had no idea what I was doing.

How did you get started in programming?

I remember when my dad got a new PC with Windows 3.1 on it. Prior to that, I knew how to ‘cd’ between directories and how to run ‘dir’. All of these commands were, of course, to get to the directory where my games were installed. :-) I never really stayed in Windows at the time, because all the games were still DOS-based. I didn’t really have much to do with Windows (except for the Hot Dog theme), until Windows 95 came out. That’s when I started becoming more of a computer enthusiast. I remember troubleshooting Dial Up Networking so that our 14.4 modem would connect up. I also remember buying my first piece of hardware, the 3dfx Voodoo card.

As I mentioned, I started doing some basic web pages when I was in high school. This was the time of animated GIFs and tiled backgrounds, if you’re interested. This was also back when 56K modems first came out and there wasn’t yet a clear standard on how 56K modems would talk (you could either go with US Robotics or the cheap brands) and I worked as tech support at a local ISP. It wasn’t hard to do tech support because I had been troubleshooting my own Dial Up Networking problems for a few years already.

Coming from a tech support role, I didn’t really have any programming knowledge. I knew how to build a computer and I even knew about msconfig, but programming??? Nah… not really. Just WYSIWYG HTML.

When I graduated high school, I either wanted to be a musician or work with computers. Seeing as how I didn’t really want to teach high school band, I decided to go to school to learn about computers. I didn’t really know what Computer Science meant, but hey, my grades were pretty good so why not? So, I chose a major of Computer Science and the rest is history.

What was your first language?

Unlike the rest of the programming populace, my first language was actually not BASIC, but C++. I didn’t actually write a line of BASIC until my junior year of college! I would say that I currently prefer C# over VB.NET, but it has more to do with terseness than it does with braces. For the same reason, I’m a fan of Ruby as well.

What was the first real program that you wrote?

Are you saying Hello World doesn’t count? C’mon!

I’m going to define “real program” in this case as something that I could show my parents. I couldn’t show them “Hello World” or a command line application to create a binary search tree because they couldn’t relate to it. However, I could show them a GUI maze application that I wrote in Java. It had four players (one of which could be human controllable) and then each player raced to get to the exit. I also wrote a Solitaire program in C++, a networking Tic Tac Toe game in C++, and a Paint program in C++ (using the Windows API).

My first team application, like Brian’s, was created in the capstone course at Harding. We wrote a version of Othello that had to be networked with an AI. I wrote the networking code in C#. It even had threading code, which of course was written completely wrong. I’m still not entirely convinced that I can write threading code correctly today. :-)

What languages have you used since you started programming?

In college, I primarily used C++ and C#, but I also had some exposure to some Assembler, Java, VB.NET, Perl, and even LISP! My work experience includes a (thankfully short) period of COBOL and JCL on an IBM mainframe, but primarily has been in VBScript (both classic ASP as well as scripts), Javascript, PowerShell, C++, C#, and VB.NET.

In my personal projects, I’ve used C#, VB.NET, JavaScript, PowerShell, PHP, Python, and Ruby. I’m sure I’ve missed something in there.

What was your first professional programming gig?

I got hired out of college to work at Data-Tronics, Corp. where I still am to this day. My role has changed significantly now, where I’m trying hard to push out 40 years of IT practices with more modern methodologies (down Waterfall, down!) and technologies (down Mainframe, down!).

If you knew what you know now, would you have started programming?

You bet. I’m a geek to the core.

If there was one thing you learned along the way that you would tell new developers, what would it be?

I’d have to agree completely with Brian – get involved in the community. Do not let programming become just the job you perform. Like JP, get passionate about developing. If you don’t enjoy what you do, there isn’t any point in doing it. Start reading blogs and going to user groups. You’ll be overwhelmed at how much you didn’t know, but remember that no one else knows it all either. We’re all learning together.

What's the most fun you've ever had... programming?

I can’t think of any one specific instance, but I think one of the best feelings is, after having spent literally hours trying to debug some problem and then giving up and going home, waking up the next day and having the light bulb come on with the solution to this problem. I love solving problems with software.

Tag, you’re it!

Colin Neller, come on down!
Randy Walker, you too!

I’ve got other tags if anyone else is interested. I might even give some out!

posted on Tuesday, July 15, 2008 11:36:10 AM (Central Standard Time, UTC-06:00)  #    Comments [3]
 Thursday, July 10, 2008

I was going through some code today and stumbled across the following:

Mmmmm... that was a good exception

Hilarious.

posted on Thursday, July 10, 2008 9:09:37 AM (Central Standard Time, UTC-06:00)  #    Comments [6]
 Thursday, April 24, 2008

(Warning - this post is both a rant against the Mutex as well as a guide for its usage. Also, don't blindly copy code, only the bottom code snippet works. :-) )

I'm a big fan of an API that is so easy to use that I don't have to look at the documentation.

I had to look up the documentation for System.Threading.Mutex... multiple times.

Taking a look at Mutex, I see that it implements IDisposable. Great, that means I can wrap it in a using block.

My first try:

bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
    MessageBox.Show("Press OK to release the mutex.");
}

Looks good, right? Nope, that is a big negative. Nowhere does this actually acquire the mutex. When you run this application twice, they both show the message box just fine. Maybe I should actually check the createdNew value?

Let's change the code to look like this:

bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
    if (!createdNew)
        mtx.WaitOne();
    MessageBox.Show("Press OK to release the mutex.");
}

However, that didn't work, either. It turns out that the createdNew parameter just tells you if you're the one who created the mutex, not if you currently own the mutex. That is what the purpose for the WaitOne method is for. Of course, the documentation just says that it "blocks the current thread until the current WaitHandle receives a signal." Okay. Well, I'm glad that I now know that it also waits for my thread to acquire a lock on the mutex. (note, if you pass in 'true' as the first parameter, you'll request to be the owner, but you'll only be the owner if the createdNew out parameter comes back with true)

Third try. Third time's the charm, right?

bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
    mtx.WaitOne();
    MessageBox.Show("Press OK to release the mutex.");
}

Great, now when I run my app twice, the second one is blocking on the WaitOne call. Cool. You can even tell in the below screenshot, because the button's paint event is blocked and is whiting out (like Solitaire does when you win!).

image

Let's click okay and see if the second form gets the mutex, thus displaying the message. That's weird - the form still isn't responding. Let's close the first form.

image

Ouch! That was unexpected. What? Abandoned mutex? This sounds like I never even released the mutex. Hmmm... ReleaseMutex? Shouldn't that be called from the Dispose (end of the Using block)? Might as well try it.

bool createdNew;
using (Mutex mtx = new Mutex(false, "MyAwesomeMutex", out createdNew))
{
    try
    {
        mtx.WaitOne();

        MessageBox.Show("Click OK to release the mutex.");
    }
    finally
    {
        mtx.ReleaseMutex();
    }
}

Finally! Now, it works like I'm wanting. I'm keeping the using block in place, because that disposes the WaitHandle that Mutex uses (Mutex in face inherits from WaitHandle).

Anyway, I'm hoping there is a reason for the API to be designed in this way, but man, it doesn't seem very intuitive to me.

While learning this, I unfortunately tried putting the Mutex in some of my code without trying it small scale first. After struggling for quite a while, I went to the small application and discovered everything that I've posted here. I hope this helps you with the Mutex when you have to deal with it.

posted on Thursday, April 24, 2008 2:48:19 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, February 05, 2008

I've found myself wishing that I could pass in more than two arguments to Path.Combine. That is, something like this:

Path.Combine(rootPath, someCalculatedPath, someKnownFileName);

As it is, Path.Combine only accepts two arguments, so I end up with calls that look like this:

Path.Combine(Path.Combine(rootPath, comeCalculatedPath), someKnownFileName);

It seems like a hassle to me. Here is a simple wrapper function (with accompanying test) that will accomplish this:

public static class FileUtils
{
    public static string CombinePaths(params string[] paths)
    {
        if (paths.Length == 0) return string.Empty; 

        return Path.Combine(paths.First(), CombinePaths(paths.Skip(1).ToArray()));
    }
} 

[TestFixture]
public class FileUtilsTests
{
    [Test]
    public void Should_combine_paths_correctly()
    {
        string expected = @"c:\some\path\to\file.txt"; 

        Assert.AreEqual(expected, FileUtils.CombinePaths("c:\\some", "path\\to", "file.txt"));
    }
}
posted on Tuesday, February 05, 2008 7:29:02 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Wednesday, January 30, 2008

In my post looking forward to 2008, I mentioned that I wanted to take more time this year to learn new technologies, particularly outside of the Microsoft communities. With all of the push in .NET towards dynamic languages right now, why not look to some of the dynamic languages that have been out there being used for years?

I know what you're thinking - looks like David here decided to learn Ruby. I mean, that's what everyone is using, right? Ruby and Ruby on Rails? Nahhh, I'm actually learning Python! Probably the key factor for me was the Python Challenge. I follow MoW's Powershell blog and he's started up a series on working through the Python Challenge using Powershell. I had heard about the challenge before, but hadn't really looked into it much, but this was enough to prompt me to get over there and try it out. (I am planning on still learning Ruby, though - I'll just go through the challenges with Ruby later)

I resisted the urge to try to find an IDE for Python and just code it up in a text editor. It has forced me to get more familiar with the syntax as a result. The Python site has a great tutorial for starters as well as some good documentation on the available modules. The hardest part for me is to not write the code like I write C# or VB. For one of the challenges, you have to take a given string, a given mapping, and then translate the string to get the instructions to move to the next challenge. I wrote a basic loop over the characters in the string, converted them to their ordinal values, performed the translation, and then converted them back to characters. It worked, but it wasn't the best way to do it in Python. Python provides this great function called string.maketrans. Also, the map function is amazing. It is sort of like the List<T>.ForEach method except that it reads a lot better (though lambda expressions in C# make it a little better). I'm starting to understand the power behind the whole map/reduce idea that Google is so big on. List comprehensions are really cool, too.

Anyway, so far, I'm to the 5th challenge (with some help from Google, the Python tutorials, and the challenge forums at times) and it is pretty cool. One of the most enlightening things about going through the challenge is that, as you complete one, you can go look at submitted solutions on the wiki. It is a great way to evaluate if you solved the challenge the "right" way or not. It is a great learning experience. One way I'm trying to apply this knowledge is that I'm running the challenges in both CPython (Python that runs on C, the standard I think) and IronPython.

Another thing I've done to try to see how other development communities work is that I've installed Ubuntu 8.04 (the alpha) on my laptop. I'm now dual booting Vista x64 and Ubuntu and it is pretty nice. I have two favorite things about Ubuntu so far - the ridiculous customization that you can do with it (compiz is amazing) and the package manager. Seriously, the fact that you don't have to pull up a browser to download apps and install them is a massive plus over Windows. In fact, you can just run a simple apt-get command if you want. Don't worry, though, I'm not planning on switching from Vista anytime, soon. Ubuntu is great and I'll be keeping it on the laptop, but I still like Vista, too. Right, right, blasphemy, I know. They're both great operating systems as far as I'm concerned. One takes an entire DVD and seems like a resource hog (not as bad anymore) and the other fits on a CD and requires editing conf files, downloading "restricted" drivers, and sitting at the command line to get video and wireless working :-) Seriously, neither are perfect. It has been nice seeing both sides of the fence, though.

posted on Wednesday, January 30, 2008 8:11:42 AM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Thursday, December 06, 2007

In case you've been under a rock recently, Visual Studio 2008 was released recently which supports a lot of functional capabilities like lambda expressions. I've been playing around with the lambda syntax in both C# and VB.NET recently and the addition to the languages is great. I did run into one thing that is still frustrating me in VB.NET, though.

Check out the below C# snippet:

TryTimes(() =>
{
   Console.WriteLine("hi there.");
   throw new Exception("haha");
   Console.WriteLine("hi there after   .");
}, 5);

This is the prototype for the usage of a function that could try an operation a certain number of times and then fail if the operation didn't succeed after N number of tries. Obviously, the above code sample will fail every time, but the idea could work alright for file I/O if you're unsure if anyone else might have locks on the file.

The above is impossible to do in VB.NET, though, because VB.NET does not support multi-line lambda expressions. The C# supports them by wrapping the expressions in curly braces, essentially making the lambda expression a block. I wanted to emulate the same thing with VB.NET, but after some fruitless web searches, I came across this MSDN forum posting on VB.NET and lambdas which then pointed to Paul Vick's post on the VB 2008 features that are still in.

I've been wanting the equivalent of anonymous delegates in VB for a long time and I thought, with lambda expressions, I might finally get them. We are a lot closer, but they still don't provide quite the benefit that they could have had we gotten multi-line lambda support. I guess those annoying line continuation characters in VB mess this all up. I think if I could change anything about VB, it would be to make those optional.

On the positive side, though, the intellisense support for VB.NET has increased substantially. For that, I am thankful.

posted on Thursday, December 06, 2007 9:56:03 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, November 14, 2007

I'm close to finishing up some work on one of my first true TDD projects and it has gone great for the most part. It did take a long time to get started though. The hardest part for me was fighting the urge to just open the designer and start dropping controls. Visual Studio really does guide developers towards a designer-centric approach which, after having done this for a few years, is very hard to resist. What I ended up doing was thinking about the problems that this application was going to solve and starting there. Make your tests define the problem area and move outward. The idea is that, if you can't write your tests that show what your code will do, are you even ready to write the code yet?

I was able to get my first few tests out quickly, but then I hit a block where I struggled with the structure I wanted to follow. This turned out to be good because, instead of coding something up that was substandard, I was able to fight through this struggle and come out with a better solution in the end. In doing this, I discovered a great benefit that TDD provides - you can continue coding even if you don't know all of the answers to all of the problems that your application will solve. For example, I'm still not sure what file format I'll be using in my application (or even if I'll use the file system). It really doesn't matter, though, because I was able to set up an interface and mock that dependency out in my tests and continue with the rest of my application. Had I started with the designer, I likely would have sat around until I had hashed out the file format requirements.

Once I got past my initial hang ups, I was able to fly through the rest of the code. What is even better is that I feel a huge amount of confidence in this code - code that still has no UI around it. I haven't felt this good about code quality in, well, ever.

If you're wanting to start with TDD, I'd like to recommend a few resources. First, read more code. If you aren't using it yet, go get TortoiseSVN and pull down some open source code. The Rhino.Commons repository is an excellent source of code (as well as great utilities). I can also recommend Jeremy Miller's StoryTeller code. I don't do anything with FIT tests, but the code is still a great example of WinForms code driven by tests.

Another great resource is screencasts. Watching someone write their tests first helps immensely. Evan Hoff has a great screencast on TDD. It also shows some of the power of ReSharper.

One final thought for this post is something that Bob Martin spoke about in this Channel 9 interview on programming discipline. Bob pointed out that few disciplines are as fragile as programming is. For example, if even one bit is off in your application, it has the potential to crash. One example of a profession that is also fragile is accounting. If one digit is off in the wrong spreadsheet, the CEO of a corporation can get thrown in jail. The way that the accounting profession has solved this is by entering their numbers twice - with credits and debits. If something gets entered wrong, it won't balance. When the sheets balance, there is confidence in the reported numbers. In the same way, TDD and unit tests provide the balance and confidence that applications are doing what they were intended to do.

Technorati tags: ,
posted on Wednesday, November 14, 2007 12:56:48 PM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Wednesday, October 31, 2007

It is Halloween after all. It would be a great day to start learning Boo.

Sorry. I couldn't help myself.

posted on Wednesday, October 31, 2007 12:46:36 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, October 18, 2007

I was reading through my feeds this morning and came across this gem of a paragraph:

Manual testing is immoral. Not only is it high stress, tedious, and error prone; it’s just wrong to turn humans into machines. If you can write a script for a test procedure, then you can write a program to execute that procedure. That program will be cheaper, faster, and more accurate than a human, and will free the human to do what humans to best: create!

The paragraph is actually an aside to the rest of the post, too! Go read the entire TDD post in context at the ObjectMentor blogs.

posted on Thursday, October 18, 2007 7:15:18 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, September 28, 2007

One of the banes of my existence (okay, not that bad but fun to say) is supporting Windows 2000 at work. Yes, there are still Win2K machines out there - not many, but enough to make a difference. One problem is that .NET 3.0/3.5 isn't supported on Win2K, so we're limited in what we can do, at least on the client-side. Another problem is just strange issues with the framework. 99% of the stuff we write works great, but there are a few things that don't.

Here is one that caused mass confusion recently.

Check out the code for this incredibly simple console application that I wrote:

Module Module1
 
    Sub Main()
 
        Console.WriteLine(">>Environment.CommandLine = {0}", Environment.CommandLine)
        Console.WriteLine(">>Environment.GetCommandLineArgs()(0) = {0}", Environment.GetCommandLineArgs()(0))
 
        Dim commandLineFileName As String = System.IO.Path.GetFileName(Environment.GetCommandLineArgs()(0))
        Console.WriteLine(">>commandLineFileName = {0}", commandLineFileName)
 
        Console.WriteLine(">>ProcessName = {0}", Process.GetCurrentProcess.ProcessName)
 
        Console.WriteLine("Press enter to continue....")
        Console.ReadLine()
 
    End Sub
 
End Module

What would you expect the output to be?

Here's what it does on Windows XP:

>>Environment.CommandLine = ConsoleApplication1.exe
>>Environment.GetCommandLineArgs()(0) = ConsoleApplication1.exe
>>commandLineFileName = ConsoleApplication1.exe
>>ProcessName = ConsoleApplication1
Press enter to continue.... 

On Windows 2000, it does the same thing. Super.

Let's change the name of the executable to ThisIsALongNameForAnExe.exe and run it again.

>>Environment.CommandLine = ThisIsALongNameForAnExe.exe
>>Environment.GetCommandLineArgs()(0) = ThisIsALongNameForAnExe.exe
>>commandLineFileName = ThisIsALongNameForAnExe.exe
>>ProcessName = ThisIsALongNameForAnExe
Press enter to continue.... 

Once again, Windows 2000 behaves the same way. Great.

Let's try one more thing. Let's change the name of the executable to This.Is.A.Long.Name.For.An.Exe.exe and run it one last time.

Windows XP looks like this:

>>Environment.CommandLine = This.Is.A.Long.Name.For.An.Exe.exe
>>Environment.GetCommandLineArgs()(0) = This.Is.A.Long.Name.For.An.Exe.exe
>>commandLineFileName = This.Is.A.Long.Name.For.An.Exe.exe
>>ProcessName = This.Is.A.Long.Name.For.An.Exe
Press enter to continue.... 

However, Windows 2000 looks like this:

>>Environment.CommandLine = This.Is.A.Long.Name.For.An.Exe.exe
>>Environment.GetCommandLineArgs()(0) = This.Is.A.Long.Name.For.An.Exe.exe
>>commandLineFileName = This.Is.A.Long.Name.For.An.Exe.exe
>>ProcessName = This.Is.A.Long
Press enter to continue.... 

Can you tell the difference? System.Diagnostics.Process.ProcessName is truncated when running on Win2K. The only thing I can tell is that the periods in the process name throw it off. Granted, hopefully you don't have anything secure relying on the name of your process (cough, rename, cough), but it still came across as very unexpected.

Note - the results can be different depending on how you actually execute the program. The command line and command line arguments are literally what was typed when the program is executed.

posted on Friday, September 28, 2007 1:21:13 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Wednesday, September 26, 2007

Yesterday, I had a somewhat strange experience. I was helping someone with a problem they were having and, almost as a side note, this individual thought he would share some code with me that he was particularly proud of. He even prefaced the story with the "not to brag or anything" phrase. He had written some custom code to help text boxes grow or shrink depending on how the user resized the window. If you know anything about WinForms, you'll know that some simple anchoring techniques and good use of the SplitContainer will solve this problem for you - please, please, please don't go writing custom mathematical equations when the framework can take care of it for you.

At the time, I was pretty annoyed with it, because this individual was bragging about something that I considered "the wrong way to do it." In retrospect, this probably was the wrong response. Why? Because he was proud of some of the code he had written. He actually cared about it enough to not just treat it as something to toss off on to someone else when he moved to the next project.

The projects that have turned out best that I've worked on the ones where I was really proud of the code. That doesn't mean I did it the right way. I'm thinking of one example where I wrote this crazy elaborate dynamic menu system in JavaScript. It even worked in both Firefox and Internet Explorer. It had a full blown object model and made use of closures and more - it was great. Here's a complete example of usage of the menu:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
   <head>
      <title>clsNavBar</title>
      <script language="JavaScript" src="clsMenu.js"></script>
      <link href="styles.css" rel="stylesheet" type="text/css">
   </head>
 
   <body>
      <script language="JavaScript">
        var nav = new clsMenu();
        nav.setContainer(document.body);
        nav.setXMLUrl("NavBar.xml");
        //nav.setHorizontal(false)
        nav.buildMenu();
      </script>
   </body>
</html>

It had one problem. Maintenance. Maintenance on the system will be nigh impossible for the next guy. From the very beginning, I should have used CSS for the entire menu structure. When and if someone ever decides to change the way the menus look, well... good luck. However, it was still a good experience. I learned more about the inner workings of JavaScript from working with that than I did from any blog post or book I've ever looked at. I would have never learned what exactly 'this' references in JavaScript without that example (see this post on JavaScript gotchas and refer to the section on 'this').

In all of this, I have learned to be very careful of the code I'm proud of. Inevitably, if you're growing as a developer by "sucking less every year," you're not going to be too proud of your code in a year or two anyway.

Do you have any code you're particularly proud of? If it turned out to be the "wrong way to do it" but you learned a lot from the experience, you get bonus points.

posted on Wednesday, September 26, 2007 7:17:19 AM (Central Standard Time, UTC-06:00)  #    Comments [2]
 Thursday, August 30, 2007

I was messing around with some unit tests this week and I came across an unexpected benefit while working on code that worked with a COM object. When you add a reference to a COM library in .NET, you'll get an interface as well an implementation of that interface that forwards the calls to the COM objects.

Because an interface is created for the COM objects as well as the implementation, you can mock the COM dependency with Rhino Mocks or some other mocking framework. Just code against the interface instead of the concrete implementation and inject the concrete implementation via dependency injection for the normal scenario.

Let's say you wanted to unit test some code that had a dependency on the Windows Media Player COM object. Here's how you could do it.*

image

// Code to be tested
public class SomeClass
{
   private WMPLib.WindowsMediaPlayer _player;

   public SomeCode(WMPLib.WindowsMediaPlayer player)
   {
      _player = player;
   }

   public void DoSomething()
   {
      _player.enabled = false;
   }
}

// Unit test
[TestFixture()]
public class SomeCodeTest
{
   [Test()]
   public void PlayerEnabledShouldBeSetCorrectly()
   {
      MockRepository mocks = new MockRepository();

      // Mock the WMP interface... note that even 
// though it doesn't start with an 'I', // it is still an interface... WMPLib.WindowsMediaPlayer player = mocks.CreateMock(); // Inject the mocked WMP object SomeClass sc = new SomeClass(player); using (mocks.Record()) {
// Expect player.enabled to be set to false player.enabled = false; } using (mocks.Playback()) { sc.DoSomething(); } } }

I tried this code out and the test runs fine. Note the comment where the mock object is actually being created. For some reason, the interface to the COM object isn't named with an 'I'. It still is an interface, though. And you can create the COM object by saying 'new WMPLib.WindowsMediaPlayer' though I think that is some COM interop magic going on there (I'm guessing the CoClass attribute on the interface has something to do with this magic).

* I'm not actually mocking Windows Media Player in any of my code and I have no idea how well it will work. I do know that I can mock some of our own COM objects without any problems, though.

posted on Thursday, August 30, 2007 3:36:44 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, August 21, 2007

I found myself writing the following code this evening:

public T GetItem<T>(string name)
{
    string result = node.SelectSingleNode(name).InnerText.Trim();
 
    return (T)GetConverter(typeof(T)).ConvertFromString(result);
}
 
private TypeConverter GetConverter(Type objectType)
{
    if (objectType.Equals(typeof(int)))
        return new Int32Converter();
    else if (objectType.Equals(typeof(bool)))
        return new BooleanConverter();
    else if (objectType.Equals(typeof(string)))
        return new StringConverter();
    else
        throw new ArgumentException("Does not support casting to " + objectType.Name);
}

Don't ever write code like this. Read the documentation which explicitly says that "you should never create an instance of a BooleanConverter". If you follow their advice, your code will become much cleaner. Like so:

public T GetItem<T>(string name)
{
    string result = node.SelectSingleNode(name).InnerText.Trim();
    return (T)TypeDescriptor.GetConverter(typeof(T)).ConvertFromString(result);
}
posted on Tuesday, August 21, 2007 8:39:58 PM (Central Standard Time, UTC-06:00)  #    Comments [0]

I was looking through programming.reddit.com today and discovered that IronLisp now has a website on Codeplex. I haven't coded in LISP since college, but it was certainly an interesting experience.

This got me thinking - how many Iron* projects are there now? This is what I've come up with:

1) IronPython - the original Iron project?

2) IronRuby

3) IronLisp

4) IronXSLT - (thanks Michael!)

5) ...

Hmmm... as I was thinking about this blog post, I seemed to think there were a lot more out there. I know there are a lot of other languages that support the CLR, but I guess the Iron designation seems to be fitting with the languages that are build on top of the DLR. I'm a little curious if the Smalltalk/DLR implementation (Vista Smalltalk) will make the name change to IronSmalltalk or not.

So where did the Iron naming scheme come from anyway? Why not Nython1 or NRuby2? :-)

1 - The Java implementation is Jython.

2 - The Java implementation is JRuby.

posted on Tuesday, August 21, 2007 6:47:02 PM (Central Standard Time, UTC-06:00)  #    Comments [3]
 Tuesday, August 07, 2007

I work with the WebBrowser control that was introduced in .NET 2.0 (as well as the ActiveX browser it is based on) a lot at work. As a result, I've come to learn a lot about some of the various intricacies that Internet Explorer has as well as the browser control in general.

Because we're not running some of our web pages in Internet Explorer but in a custom web browser, unit testing frameworks like Watir and Watin won't work for us. They make use of the Internet Explorer COM application. Unless we want to fork one of those frameworks as well as provide an automation interface into our custom browser, I don't see either of those frameworks working for us.

However, Selenium will work fine!

Selenium runs in the browser!

image

That's a picture of a little WinForms application I put together that is hosting the WebBrowser control. As you can see, all but one of shipped Selenium tests passed (the only one that failed had to do with opening an XHTML page).

Looks pretty good to me!

posted on Tuesday, August 07, 2007 12:51:25 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, August 02, 2007

(note - if you're reading this in a feed reader like Google Reader, sorry - the code snippets look awful... if anyone has any suggestions on good ways to get code to look good in the webpage and feed readers, I'd appreciate it)

Given this:

    delegate void WorkDelegate();
    interface ISomeInterface
    {
        void Execute();
    }

 

What is the difference between this class

    class TestCaseOne
    {
        ISomeInterface something = Activator.GetObject(typeof(ISomeInterface), "http://some.url.com/") as ISomeInterface;

        public TestCaseOne()
        {
            BackgroundWorker wkr = new BackgroundWorker();
            wkr.DoWork += new DoWorkEventHandler(wkr_DoWork);
            wkr.RunWorkerAsync();
        }

        void wkr_DoWork(object sender, DoWorkEventArgs e)
        {
            something.Execute();
        }
    }

and this class?

    class TestCaseTwo
    {
        ISomeInterface something = Activator.GetObject(typeof(ISomeInterface), "http://some.url.com/") as ISomeInterface;

        public TestCaseTwo()
        {
            WorkDelegate dlg = new WorkDelegate(something.Execute);
            dlg.BeginInvoke(MyCallback, new object[] { dlg });
        }

        private void MyCallback(IAsyncResult iar)
        {
            object[] asyncState = iar.AsyncState as object[];
            WorkDelegate dlg = asyncState[0] as WorkDelegate;

            dlg.EndInvoke(iar);
        }
    }

 

Both classes have a field named something that is a reference to an HTTP remoting proxy that has been published at http://some.url.com. Let's assume that the the HTTP Remoting configuration has already been set up. Both call the Execute method defined on the interface, but one is using a BackgroundWorker for threading and the other is using the BeginInvoke/EndInvoke means of threading. Big deal, right?

There isn't a huge difference just looking at the code -- except that with TestCaseOne, the remoting call will result in a blocked thread whereas TestCaseTwo will not. In TestCaseOne, the background thread will block on the something.Execute() call and wait for it to return. In TestCaseTwo, the WorkDelegate BeginInvokes on the transparent remoting proxy. There isn't any code to block on. Instead, the framework will let you know when your remoting call returns.

Why does this matter? When you have a blocked thread, you basically have wasted CPU cycles where it is blocking instead of working. This likely won't matter much if you're not working with a lot of threads, but it can cause performance problems if you're working with a lot of threads.

On the other hand, when TestCaseTwo calls back to let you know the remoting call has completed, it will not call back on the calling thread. BackgroundWorker is smart enough to invoke back to the UI thread if needed. Both have their pluses and minuses. The BackgroundWorker component does make the code a little more easy to read and it handles invoking back to the UI thread. However, if you're working with a lot of threads, you might try using the delegate approach instead, so as to avoid any blocked threads.

posted on Thursday, August 02, 2007 9:40:25 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Friday, July 13, 2007

Visual Basic annoys me because of the way arrays are initialized.

What's the semantic difference between the two lines of code below?

C#

int[] test = new int[10];

VB.NET

Dim test(10) As Integer

Here's a hint - one array has ten items and one does not. The VB.NET array has eleven elements. When you declare an array in VB.NET, you're specifying the upper bounds of the array instead of the length. This drives me insane. We regularly go between C# and VB.NET and I am constantly bit by this one.

I was talking with a guy at work today and we discussed how we'd like to have another option setting (in addition to Option Strict and Option Explicit) available for VB.NET:

Option OperateLikeAllOtherLanguages = True

This setting would allow VB.NET to initialize arrays like all other languages.

NOTE: This post is satire. I still like to program in VB.NET and C#. I do not want to get into which language is better. Both languages have their virtues. Learn them both. Then go learn Ruby.

posted on Friday, July 13, 2007 1:02:19 PM (Central Standard Time, UTC-06:00)  #    Comments [1]
 Thursday, July 05, 2007

In the few years that I've worked as a software developer, I've read and seen many examples of testing software. As a result, my own thinking regarding testing has changed drastically over the past year or two. It seems that there is a continuum behind the thinking that goes behind testing. I originally titled this post "the Evolution of Testing Thought Processes" but evolution doesn't describe this as well for me, because I find myself moving between the different processes depending on the circumstances.

This post has a few goals:

  1. I want to gain a better understanding of where I stand regarding testing code.
  2. I want to share some of these ideas with others, particularly my coworkers, who might not have encountered ideas like unit testing.
  3. I want to get your input on this and see if anyone else struggles with these issues, too.

 

Here are the different thought processes that I've seen regarding testing:

No Testing (i.e. did it compile?)

This one's easy to categorize, right? Basically, no testing happened whatsoever. If it compiles, you're set. If you're working in a dynamic or interpreted language, then good luck. Hopefully, you've never seen this one before, but I wouldn't be surprised if you have.

I have a horror story to share regarding this. A few years ago, my team was on track to install a fairly substantial update to a daily scheduled application. The update unfortunately required some changes to the script that kicked off the whole process. Because my team didn't own this script, we had to get someone else to do it. What we didn't know is that a certainly individual who will remain nameless decided to convert this script from REXX to VBScript. This would have been a good change at the time, had we prepared for it. Needless to say, this wasn't even the worst part.

This individual never even attempted to run this script.

You heard me - this individual converted a script from one language to another one and never tested the script at all. How could I possibly know this when I didn't even know the script was being converted? Because when the script was scheduled to run the next day, it blew up. It blew up because of invalid syntax. It blew up because there was VBScript code at the top... and REXX script at the bottom. I spent the better part of two days attempting to fix that problem.

The lesson here is to at least run your application once before installing. I don't care if you're the best developer in the world. You can still make mistakes.

Don't do this.

 

Manual Testing (i.e. F5 testing)

Manual testing is when developers run their application and attempt to test all of the functionality themselves. If they don't spot any problems, then the application is ready for production.

I used this technique the most while in college. If my professor could break our application with invalid input, then our grade would drop. For each problem the professor found, the grade would continue to drop. The majority of the applications that I wrote during this time were command line applications, so most of the user interaction was pretty easy to verify. I missed a few edge cases sometimes, but I was able to test the basic functionality because the application itself was so simple.

I consider having someone else test your application an example of this as well. My experience is that usability problems are discovered here instead of bugs. The problem is that most developers have their own projects to work on, so testing your application isn't exactly at the top of their list of things to do. In other words, their testing will likely be even less rigorous than your testing.

 

Manual Unit Testing

This is a small variation on manual testing the whole application. At this point, you are testing smaller units rather than an entire application, which is a good thing. To do this, you typically have either a command line interface, a small form or a small web page that uses the small unit from your application. Your UI likely performs a few actions on your library and you then examine the results for problems. Sometimes, you'll enter a few input details to test different scenarios. Ideally, you'll test as much of the functionality that the library provides as possible.

The most common place I see this is when someone has written a shared component or created some external assembly that will potentially be used by someone else. It doesn't have a UI of its own, so to test it, you have to create something else to run it.

On the testing continuum, this is the first case where application testing is broken up into pieces. Developers can test parts of the application separate from the rest. As a result, there is less to distract developers.

 

Unit Testing

The problem with manually testing units of an application is that verification of the results is still dependent upon the developer. Everyone makes mistakes so it is only a matter of time before someone misses a problem. Unit Testing takes the last approach and expands upon it by letting the computer decide whether or not your library is working correctly.

With a manual test application, you simply look at the results that your test UI provides. Why not put those results (expectations) into code? The test can then be much more precise about its results. For example, it is much easier to determine if a returned numeric type is an integer or decimal value from code than you can from a UI. In .NET, you can just check the type. Better yet, you know immediately from code whether or not that is a "0" or an "O".

These tests provide value during development time, but particularly during maintenance time. Imagine that a user of your system decides that they want to change something. Crazy, right? Have you ever made a change to an existing system and then broken existing functionality elsewhere in the application? This is why regression testing is necessary. Unit testing makes regression testing even easier because the list of tests you have stays with the application. As you find new bugs, you can write tests for those so that they never show up again.

Tool support for unit testing is awesome, too. With tools like MbUnit, NUnit, TestDriven.NET and others, it is easier than ever to write and use unit tests. The tools get better with each release, too. One of the things that is nice about the unit testing libraries available is that they all have test runners that generate reports. This allows you to automate the testing and tie it into your build process or test your code nightly or whatever. That is one of the ideas behind Continuous Integration. Every check-in of an item into source control results in a build script running which can also run tests. Not only do you find out if you broke the build, you also find out if your tests now fail.

One of the problems that people have with unit tests is that they feel like they spend twice as long on code because they're writing tests in addition to the code that will run on a user's machine. Doesn't that increase development time? In my experience, it adds to the time (though not twice as long) of the first iteration of software development, but it can significantly cut down on latter iterations. Have you ever maintained legacy code? I hate working with legacy code because half the time I end up breaking existing functionality. With unit tests, when I later have to come in to change a program, I can feel confident knowing that I'm not breaking existing functionality.

 

Test Driven Development

How about writing your unit tests first? That will blow your mind the first time you think about it. The idea behind Test-Driven Development isn't so much that you're writing a test first as you are designing the contract for your class from the outside. Proponents of test driven development very often state that this development methodology helps drive their design more than providing a good test framework. The test framework is an added benefit to good and extensible design.

This is the hardest of the thought processes behind testing to really grasp, at least for me, because it requires a change in the way you think about developing software. Some don't see the benefits from it and others wouldn't program without it. I certainly can see the value in it, but I haven't had enough real world experience actually doing it to be effective with it yet.

 

So, did I miss anything? Where are you on the testing continuum? I find that I move back and forth between Manual Unit Testing and Test Driven Development. I'd like to move more towards TDD, because it is certainly beneficial and I find that code designed with testability in mind is much easier to modify later.

One thing to remember is that all of these ideas play a part in testing an application... except for the not testing idea. At some point, you'll need to actually run your application to try it out. If you employ unit tests, they'll simply provide more confidence in the application and provide future insurance when the code changes - and it will change.

For more information, check out this software testing article on Wikipedia.

posted on Thursday, July 05, 2007 1:12:09 PM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Tuesday, June 19, 2007

I just completed the Classic Mistakes survey from Construx. Thanks to Jeff Atwood for pointing this one out.

The survey itself didn't seem particularly helpful, but the questions it poses do help in enumerating many of the problems I've experienced by actually putting them into words.

It also is beneficial to me because some of these mistakes stem from the developers instead of the management. I've been guilty of developer gold-plating and the silver-bullet syndrome many times, which is likely a result of being a beta junkie. We're in the process of moving to .NET 2.0 (no, not even .NET 3.0 or 3.5 yet) and I'm already jumping to move to Visual Studio 2008 (formerly Orcas). I mean, surely WPF, Linq, and WCF would solve all of our problems wouldn't they? Or, if we suddenly went 100% with Test Driven Development, all of our problems would disappear! Wouldn't they?

Sam Gentile's comments on writing maintainable code are very relevant to silver-bullet syndrome. He points out that the XP methodology revolves around 12 practices and not TDD by itself. TDD isn't a silver bullet but instead is a tool to help document and protect your codebase. You also have to work at refactoring your code and keep it clean and simple.

I haven't ever worked in an XP/Agile environment before, but I do like the goals that it strives for. I'm really pushing my team to learn more about architecture, design, and unit testing because I really do see the value. We really have to just start using these tools. Otherwise, we'll keep talking about them and never actually do anything.

Thank goodness for all these tech blogs. I've learned more from reading these in the past couple of years than I have from just about anything else. It's almost like I'm being mentored by all of the more experienced developers.

posted on Tuesday, June 19, 2007 8:52:51 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, April 12, 2007

Scott Hanselman recently posted about a bug that can occur when using Firefox as your default browser. The root problem deals with Outlook trying to start up Firefox using DDE instead of just a simple command line argument. At work, we ran into a very similar situation, because we were wanting to open up URLs in the default browser from our application. Normally, this would be easy because all you would have to do is Process.Start the URL without providing an application and ShellExecute would handle the rest for you. Needless to say, this wasn't going to work for us because we had overridden the default open action for URL shortcuts with our own action (it's a long story that I won't go into in this post).

Our solution started with pulling out the default browser from the registry (we still kept the original open action command, see HKEY_CLASSES_ROOT\HTTP\shell\open\command). Once we have the value, we thought we would be able to Process.Start the command line from the registry passing in the specified URL. We tested it out in Firefox and everything worked great. Even better, Firefox would reuse windows based on the user-defined settings.

Not so with Internet Explorer. Internet Explorer would open the URL for us, sure, but it would not respect the user-defined settings on the reuse of windows. This was confusing to us, because Outlook was smart enough to get Internet Explorer to reuse windows. The question was how it was happening... and that's where DDE came in.

When Outlook opens a URL shortcut, it connects to the DDE IExplore server on the WWW_OpenURLNewWindow topic. If he is able to connect, then Internet Explorer is already running. He then sends an XTYP_EXECUTE transaction passing along the URL. If everything works correctly, then Internet Explorer will open the new window and bring it to front for you. If no Internet Explorer instances are running, Outlook will start a new instance.

In case you were wondering, this was all verified using DDESpy (which you can find in the Visual C++ 6.0 Tools installation... if you still have it). It was also tested against Internet Explorer 7 and Outlook 2007 which means this information is still current.

And yet, Raymond Chen has encouraged us to stop using DDE, because "DDE has been dead as a shell interface for over ten years." Oh how I wish that the Internet Explorer team knew that. If they had, we wouldn't have had to code up DDE to get similar behavior in our application. And let me tell you, DDE is not fun to code against. There are very few resources covering DDE on the Internet (probably because DDE died before the Internet became really widespread... or not).

posted on Thursday, April 12, 2007 7:54:14 AM (Central Standard Time, UTC-06:00)  #    Comments [0]
 Thursday, March 29, 2007

If you're not already subscribed to Jeremy Miller's blog, do so now. I'll wait for you to come back.

Okay, now that you've done that, read his latest post on sunk costs and architectural decisions. I'll keep waiting.

Done? Good.

As I was reading his post, I found myself nodding my head i