Saturday, April 19, 2008

ALT.NET - Day 1

I’m up here in Redmond for the the 2nd ALT.NET Open Spaces gathering.  The first one was truly a great event.

Unfortunately I flew up Friday afternoon and missed the Friday night fish-bowl session.  I had to miss this last year as well, and next time I want to come up early enough to participate.  The fish-bowl session (from what I gather) is a rount-table discussion about the topics that should be covered in the open space the following 2 days.  If you want to learn about F# or Git, shout it out!  If you want to talk about jQuery or BDD, then let it be known.  People gravitate to the good ideas and that’s what’s covered.

I decided to rent a car and drive to my hotel.   I figured it would be cheaper than taking a taxi and easier than bumming rides off of others.  I checked in and quickly headed over to DigiPen, where the conference is being held.  Stupid me, I forgot my jacket and it was snowing!  I ran into Eddie Bauer next to the hotel and picked up a jacket to keep me warm.

digipen-nintendo-buildings

The campus is next to Nintendo, as you can see in the picture.  I’ve heard that DigiPen graduates are guaranteed internships at Nintendo.  That’s awesome.

I ran into Brian Donahue, Dave Laribee, James Thigpen, Raymond Lewallen at the front.  Inside the main room there were about 120 geeks all chatting intensely.  I glanced around and saw many known faces in the industry.

After a while a bunch of us headed over to Desert Fire, a southwestern grill near the hotel.  The room was probably going to exceed fire code and would definitely impede us getting some much needed food (and beer!) so a few of us decided to go get a different table.

If you’re on twitter, then check out the hashtag #altdotnet to see the live tweets about the conference.  For me, I don’t do much mobile tweeting, but I might post a thing or 2 during the day, so follow @subdigital if you’re on twitter.  Here is Jeffrey twittering on his phone at the restaurant:

IMG_0197

Next to Jeffrey was Jean Paul Boodhoo, who was chilling out with a large glass of milk:

IMG_0198

Here is the rest of the table:

IMG_0199

There’s Evan Hoff, Chris Patterson, Dave Woods (forgot your last name!), Dru Sellers (behind Dave), and one of Chris’ co-workers, (I forgot your name as well!).

After dinner it was drinks and geek discussion in Phatboyg’s hotel room.  Here’s the night’s progression:

IMG_0200

IMG_0202

(luckily only 2 of those were mine, otherwise I’d be hurting this morning!)

ALT.NET day one was pretty fun, but I’m looking forward day 2.  Right now I’m off to eat breakfast with some people at Ruby’s.  Until next time!

Tags:
Tuesday, April 08, 2008

The Importance of Writing the Test First

I had a skype call today with Rob Conery and Scott Bellware (twitter) today to talk mainly about how to improve the “TDD message” of his latest ASP.NET screencasts.

One of the points of feedback Rob got on his screencast is that he had stubbed the code he wanted to test before actually writing the test.  While there was no “meat” of the code he wrote, there was still code.  And that code had some sort of design baked in already.

The topic in question was about Products.  Rob had a fictitious requirement that the discount should be displayed next to the price.  So he created something like this as a stub:

public class Product
{
	public float DiscountPercent { get; set; }
	public decimal ListPrice { get; set; } 
	public decimal AdjustedPrice 
	{ 
		get { return 0.0m; }
	}

	public decimal DiscountAmount
	{
		get { return 0.0m; }
	}
}

The intent was to test that a discount was properly applied to the product.  Of course, the test fails initially, and then you can easily go make it pass, but the first activity performed was stubbing out code, and that is design.

Instead, a failing test should show with absolute opactity that there is even a need for those properties.  The fact that you’ve written a test specification that says:

A Product with a discount percent of 10 and a list price of $100 should yield a discount amount of $10.

This becomes executable, and you know immediately that you have to implement those properties. 

“But wait?” I can hear you say, “…didn’t you just come to the same end result?”  Well, yes, here I did.  But what if while writing this code you realized that you really need to calculate this amount when you are calculating an order total, then you might introduce an order object.  Or you might have a completely different need.  The point here is that you shouldn’t just assume that you’ll need those 4 properties, or this 1 method, because you’ll likely be wrong.

This also brings out the point of having good test naming.  The test name should be so descriptive, it’s like a rule for the application.  Any new developer can come onto a project and decipher the meaning & intent of broken tests.  That is a very valuable thing to have.

If you recall the original fictitious requirement, it was “the discount should be displayed next to the price” you can see that it is a UI requirement.  It doesn’t necessarily dictate the model that you must use.

In fact, you might even come to the conclusion to use a data transfer object as a presentation model and then this piece of information could literally come from anywhere.

TDD is about design.  You’ve heard that a million times.  The obvious corollary benefit is the enforced existence of automated tests for every possible specification.  Even if you intend to write the tests immediately afterwards, you may have missed out on some critical aspects of design, such as loose coupling, or eliminating waste.  You’re also tempted to just not write tests at all.

If you skip on the test-first nature of TDD, then you’re really just unit testing, and you’re missing out on the real design benefits of TDD.

I also want to point out that I’m not picking on Rob.  He’s had way too much of that.   I think he’s doing a great job and (if done correctly) he can definitely reach a larger audience than I can, seeing that he works for Microsoft.  I also think it takes guts to submit your work to the world and, in the face of some pretty harsh criticisms, stand up and say… “Hey, why don’t you get on skype and we can talk about how much I suck!” — Keep it up, Rob!

So here’s a challenge:  those of you who think that Rob did a “disservice” to the community, I’d like to see your screencast on the subject.  Obviously there is a gaping void instead of widespread adoption, so we as a community could definitely use the material.

Tags:
Thursday, April 03, 2008

A Refreshing Take on Usability

I was browsing some high resolution dual & tri screen monitor wallpapers at http://wallpaper.panedia.com/ and I noticed something really cool.  They looked at my user agent string and resolution settings to determine which wallpaper was best for me.

Considering that (without 3rd party add ons) Windows can't display more than 1 image on multi-monitor setups, you have to choose 1 large image.  They were nice enough to highlight the correct resolution as well.  Kudos to Panedia for that!




(note:  there were a ton of sizes available, my highlighted suggestion was way at the bottom)
Tuesday, March 18, 2008

Speaking at North Houston .NET User Group

Sorry for the late notice on this one (it sort of snuck up on me!)  I’ll be speaking at the North Houston .NET User Group (yes I said North, it’s new).  The talk is scheduled for Thursday, March 20th @ 6:30PM.  The meeting will be held at Montgomery College in The Woodlands.

I will talk about adopting agile development… the what, why, and how.  Hopefully it will be more of an interactive discussion, as there the audience can usually relate to the pain points that I talk about with traditional waterfall development.

For more details, check out their website.

Saturday, March 15, 2008

Debugging Routes

Previously Scott Hanselman pointed out that in CodeCampServer we are using a tiny wrapper around MvcRouteHandler in order to catch all exceptions and provide the route information along with the error message.  I called this (for lack of a better name) BetterMvcRouteHandler.  That’s right, Better!

Scott took this a mile further and created a nice route debugging table that you can use while debugging.  You can download this route debugger on Phil’s blog (with source).

To enable the route table debugger, you have to add this line to your global.asax:

RouteDebug.RouteDebugger.DebugRoutes(RouteTable.Routes);

I think it would be better to be able to add ?routedebug to the end of ANY url and have this happen automatically.  To accomplish this I created an HttpModule.  It looks at each request for the ?routedebug querystring key and, if found, calls the line above.  I ran into a hiccup, though… once you set the route handler to the debug one, all future requests use it as well (even without the url parameter). 

Good ‘ol Phil released the source for this route debugger, so I added a method to revert the routes back to their original values if the query parameter doesn’t exist.

Here is the RouteDebugModule:

Route_debug_module

(remember:  this code would NOT be appropriate for production use, both for the awkward setting of route handlers on every request and the fact that you don’t want your users to be able to see your route information.)

And the RevertRouteHandlers method (in Phil’s RouteDebugger.cs):

Revert_routes

The _oldRouteHandlers is just a static dictionary that hangs on to the route before swapping with the debug one.

I added the HttpModule to my web.config, and now I can do this:

Route-debug-in-action

…and also flip back to the regular request without recompiling.

I’m thinking they should call this BettererRouteHandler instead of RouteDebugHandler, who’s with me?

Monday, March 10, 2008

ASP.NET MVC - Preview 2 Thoughts

I said previously that I was excited for this release.  Ultimately I didn’t see much worth blogging about.  Some features are a step in the right direction, some (I think) were a step back.

I’m currently upgrade Code Camp Server to Preview 2 and hit about 80 errors which I had to go in and resolve.  My initial thoughts:

  • I think the HttpContextBase is a bad idea.  Yes I understand the desire to not introduce breaking changes.  But I think that the people that will be using ASP.NET MVC will be congnizant of this and code appropriately.  Interfaces are much easier to depend work with while testing, and I’d rather just use those.  Hey, couldn’t they give us both, and framework providers could choose?
  • what’s up with the OnActionExecuting, OnActionExecuted events?  These used to be OnPreAction, OnPostAction, which was much more readable (in my opinion) — seriously, put these back!  The new naming is not nearly as obvious to the glance.
  • Testing is still too cumbersome.  I think some good mocking-fu can mitigate this, but it’s a tough sell to people new to unit testing (and to mocking).  TempData should be implemented as an IDictionary on the controller, only to have a real TempData that depends on session state at runtime.  This would allow me to test that TempData works without having to mock session (which is not intuitive at all).
  • The Action filters are going to be where the goo lives.  This is how we will see some really productive & handy filters for performing actions such as requiring SSL, protecting an action from unauthenticated access, loading common data, etc.  Think of them as HttpModules for individual actions.

More to come, I’m sure…

 

 

Wednesday, March 05, 2008

ASP.NET MVC Preview 2 Now Available

I normally don't do this sort of announcement, but this one excites me.

Download the ASP.NET MVC Preview 2 here:
http://www.microsoft.com/downloads/details.aspx?familyid=38cc4cf1-773a-47e1-8125-ba3369bf54a3&displaylang=en&tm

Feedback to come...

Friday, February 29, 2008

Case Insensitive String Comparison is Teh Suck

Why is it so verbose to compare two strings in C# and see if they are equal, while ignoring case?

What I mean is this:  ("Apples" == "apples")  => false

Take the following examples, each of which does what I want it to, however there is so much noise code here that it really takes away from the readability of the code:

Assert.That(matches[0].Email.Equals(email, StringComparison.InvariantCultureIgnoreCase));

Assert.That(matches[0].Email.ToLower().Equals(email.ToLower()));
Assert.That(string.Compare(matches[0].Email, email) == 0);
Assert.That(Regex.Match(matches[0].Email, email, RegexOptions.IgnoreCase).Success);

Each one of these works, but I really wish this was a language feature.  Wouldn't it be nice to have a new operator syntax?
Assert.That(matches[0].Email ==? email);
//or
Assert.That(matches[0].Email ==~ email);
It turns out that we're not alone.  Ruby and Python have the same problem, however their regular expressions option is much more elegant looking (due to the languages having regex as a core feature).  This seems like such a common need that I'm surprised that this type of thing isn't built into the core of most languages.

Granted, there are concerns about how each one of these would behave, for example, how do you compare strings from two different cultures?  In my case I'm always dealing with English characters, but I fully understand the need to support internationalization.

What do you think?  Would you welcome a new operator to save your self some typing and improve readability?

The Culprit - System Restore Points

Thanks to Aaron Lerch and Scott Allen for nailing my problem exactly!  They suggested deleting system restore points and volume shadow copies.

Disk-cleanup

After doing this, I checked my free space via Explorer:

Explorer-drive-space2

42GB free now!  My santiy has returned.  Thanks guys!  My system will definitely stop thrashing with virtual memory now.

 

Thursday, February 28, 2008

Windows Not Recognizing Free Space

I’ve been having problems lately with my primary hard drive filling up.  Every once in a while Windows will tell me that I am running out of space on drive C: with only 500mb!  After I cough up my tongue I run CCleaner and do a quick WinDirStat report to see my big offenders.  Nothing glaring ever shows up in the report and I end up just deleting a bunch of old programs and other piddly files that probably only total to 1gb.  But Windows shuts up and I move on.

The last time this happened I took my World of Warcraft directory and manually (and painfully) moved it over to another drive.  This should have freed up 8gb.  It didn’t.

Today I started digging.  Windows correctly sees my drive size as 69.2GB, and reports that I only have 3.15GB free.  That must mean that ~65GB are in use.  However, JDiskReport (and WinDirStat) is showing that only 24gb are in use.

Explorer-drive-space

Jdisk-report

I ran chkdsk to get a raw view of the drive (and to see if there are any errors) and everything came out clean.  It reports that I have 15gb free!

Chkdsk-drive-space

Defrag is scheduled to run weekly and windows tells me that it doesn’t need a defrag.  At this point I’m wondering whether the drive is faulty or do I just need to reformat this drive… (I’d rather not do this, of course)

Any ideas?  I’m out of rope at this point.