# Friday, 31 August 2007

For the last week (at my new gig) I've been using ReSharper 3.0, and I must say I'm pretty darned impressed.  I hadn't looked at ReSharper since the very early versions, and had sort of written it off in favor of CodeRush/Refactor, but ReSharper 3 has some pretty compelling features...

  • ReSharper parses your code outside of the compiler, and therefore knows stuff the compiler couldn't, like when you reference something in another namespace without the proper using directive in place, and ReSharper figures out which namespace you mean, and asks if you'd like to add the reference.  Slick.
  • Inline suggestions.  ReSharper parses your code and offers up both errors (in an easier way the VS.NET, IMHO) and suggestions, such as "you really could make this field readonly".  These errors and suggestions are also displayed in a sidebar next to the scroll bar as red, green or yellow lines, so you can scroll the the problems quickly.  Nice.
  • Integrated NUnit support.  I love the way ReSharper handles NUnit integration.  You get little buttons in the right hand sidebar (where your breakpoints show up) that allow you to run or debug individual tests or the whole fixture.  The results get put in a custom results pane, much neater than the text based report you get from TestDriven.NET.  If you happen to have JetBrains profiler, that's integrated as well. 
  • Clever autocompletion.  I know I probably shouldn't be so impressed with this one, but just this morning I wrote a line that returned an IEnumerable, then on the next line typed foreach, and it completed the whole block, figured out the right types, etc.  Very clean.
  • Nice refactoring support.  I haven't had too much time to play with this yet, but it looks like it supports a goodly number of refactorings.  Cool.

I'm looking forward to playing with it more in the days to come.

Friday, 31 August 2007 09:49:06 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, 28 August 2007

So there it was, all planned out...  I had two days off (and a weekend) between jobs, and everything in place for my son and I to do a 4-day, 40 mile backpacking trip.  My last day at Corillian was last Wednesday, so I staid up late into the night packing all our gear, putting dried food into little plastic bags, trying to make sure I hadn't forgotten anything.  Thursday morning, we got the whole family up way to early so that my wife could drop us off at Santiam pass for the 4 day trip to Ollalie Lake, heading North on the Pacific Crest Trail over Three Finger Jack, Jefferson Park, and finally down into the Ollalie Lake Scenic Area. 

Alas, 'twas not to be.  As we were heading up Hwy. 22 toward the pass, all set for an early start, about 5 miles this side of Detroit the alternator in my Durango went completely dead with no warning.  Very exciting.  The better voltage fell to exactly jack, the radio shut off, lights went out, etc.  Big fun.  Luckily we made it into Detroit, where there is both food and cell coverage, but once the car was off it was dead as a post. 

Apparently there just aren't that many tow trucks working Hwy. 22, especially ones that can take a 4WD vehicle and four passengers (plus a small dog).  Between that, and actually getting the car fixed in Mill City, we lost the entire day.  There's no way we could have made 15 miles a day to do it in 3 days, since 10 was a stretch as it was.  Crap.  We ended up just going home, and retooling for a new plan.

So, they 4 day hike became a three day hike, and we decided to focus on what would have been the end of the route, around Ollalie Lake.  We (re)set out Friday morning and started hiking South from Ollalie Butte around noon.  Many fine sights awaited us along the way.

 

We camped for the night at Upper Lake, just off the PCT, and got up the next morning to keep heading South. 

This was a great opportunity to try out some new gear, and it all worked fabulously.  My new pack, a ULA Catalyst, was a joy, as was the new tent, Tarptent Rainshadow 2.  Also a big success was my new quilt, a "No Sniveller" down quilt from Jacks'R'Better.  Between those upgrades, and some other careful choices, I think I got my total pack weight to under 35 lbs., which is soooo much nicer than the 60+ lbs. I used to carry.  I'm still in the "transition" to ultralight backpacking, so I've got plenty of room for improvement.  I also have to carry a fair amount of extra stuff for the kid(s) since they can't carry quite as much.  My son's new Golite Gust also worked very well. 

The one big problem was that I have apparently lost the ability to sleep on the ground.  Something to do with the aging process, no doubt.  We brought old fashioned closed-cell foam pads, and it was hell.  In fact, I slept so poorly (plenty warm enough though) that we decided to trim the 3 day hike down to a 2 day hike, and just truck on out the second day.  This went pretty well, although made for a few more miles than the boy appreciated.  :)

We went around the East side of Monon lake, then the West side of Ollalie lake to get back to the car. 

 

Not quite the trip I'd planned, but it worked out well none the less, and a good time was had by all (except possibly the frog, who was a bit harassed). 

Tuesday, 28 August 2007 22:03:21 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  | 
# Wednesday, 22 August 2007

Things have been a bit quiet here lately, largely due to a lot of change and a lot of heads down work.  The end result is that today marks my final day at Corillian Corp. (now a part of CheckFree).  It's been a great almost 4 years of working to improve the lives of people building (and hopefully using) online banking sites, but it's time for a change.  I'm going back to consulting after a 6 year hiatus in the product world.  Come Monday morning, I start work at SoftSource Consulting where I'm hoping to continue to build cool stuff, one customer at a time. 

In the mean time, I'm off for the woods.  Hopefully I'll have some good pictures to post on Monday.

Wednesday, 22 August 2007 14:44:25 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [1]  | 
# Tuesday, 14 August 2007

You all know this.  I (in theory) know this.  However, just to remind everyone (and apparently myself)...

When debugging anything related to WCF, there are a set of problems that are IMPOSSIBLE to discover without looking at the service trace logs.  In particular (this is the one that bit me) for very good reasons, nothing security related gets as far as application code.  You pretty much get "something bad happened". 

Anyway, after beating my head against the keyboard for a good solid day, I remembered this little maxim, and checked the logs.  There was the problem, plain as day.  Doh!  Turned out that I'd changed the namespace of a particular class, and failed to propagate that change to my .svc file.  There is absolutely no indication that this was the problem at the app level, but on looking at the logs, it's right there. 

Hopefully I'll remember that one next time.

Indigo | Work
Tuesday, 14 August 2007 14:20:17 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, 23 July 2007

My apologies to anyone who tried to access this site over the weekend and found it down.  My hosting provider did some reorganizing, and some of the file system permissions got goofed.  I was out of town all weekend, and didn't know there was a problem.  Everything seems to be back to normal at present.

Monday, 23 July 2007 13:10:02 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, 18 July 2007

I decided a while back that I had too much extraneous junk running on my development machine and it was time to scale back.  Fist to go were Google Desktop, and Microsoft Desktop Search, both of which had been competing to see who could eat the most cycles and thrash my drives the worst.  Next on the list was TortoiseSVN.  Tortoise's cache seemed to be eating an awful lot of CPU time.  "How ever will I manage to deal with SVN without it?", I found myself wondering.  The reply came back "have you become completely feeble in your old age? Once you lived by PVCS, before there was such a thing as a decadent SCC GUI!". 

So I figured I'd give it a go.  The results have been pretty good so far, although it has taken me a while to get used to the svn.exe command set.  On the up side, it seems much faster than Tortoise, with updates in particular taking much less time.  The thing I find myself missing the most if the commit dialog, where you can uncheck stuff you don't want to commit right now.  Living without that makes for some extra typing, but overall it's still worth it.

The one thing that's a major hassle is browsing the repository.  If I have to figure out where someone shoved something in which repository, I've been falling back on another machine with Tortoise installed.  Lame?  Possibly.  I couldn't find anything approximating a non-Tortoise GUI SVN repository browser.  Maybe there is one, and I just haven't heard. 

So overall, I'm not quite ready to go back to edlin for text files, but the svn command line is treating me pretty well.  We'll see if I ever come to some watershed event where I decide to go back to the GUI.  That day may well come, but it's not on the horizon just yet.

Wednesday, 18 July 2007 10:57:58 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [10]  | 
# Monday, 09 July 2007

I haven't had a whole lot of time for either lately, but have squeezed in a few. 

Books

  • I'm in the midst of Scott's copy of Barry Eisler's Killing Rain.  Good fun, as always
  • I'm about half way through Herman Melville's Typee, about his jumping ship in the South Pacific.  Quite the adventure story, and much quicker pacing than the Melville I've read before (i.e. Moby Dick)
  • Sandor Ellix Katz's The Revolution Will Not Be Microwaved.  A very informative read about the state of the "underground" American food revival.  There are a lot of people out there trying to reclaim traditional and sane eating practices.  Good to know.
  • I just finished Carl Hiaasen's Tourist Season.  He can do no wrong as far as I'm concerned, and I've loved every hilarious thing I've read of his.

Movies

  • Less to tell here, I'm afraid.  Not too much has wowed lately
  • I finally saw 300, and it blew.  Totally.  Very sad.
  • My favorite of late has been Road to Perdition.  I never would have thought I'd believe Tom Hanks as a gangster, but it was a great film.  Fantastic camera angles, interesting cast, great script.  Well done.
Monday, 09 July 2007 14:30:30 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

Lately we've been experiencing one of the downsides of all the tooling we've put into our continuous integration practice.  It's fragile.  Trying to get all your tools lined up with versions that all get along is tricky, and hard to keep balanced.  Particularly when two of them (NCover and TypeMock) both try to register themselves as profiles, and have to be chained to keep the tests running while gathering coverage information.

I think we've just about got everybody moved up to the right versions, but there's been lots of "it works on my machine" the last week or so. 

The price you pay, I guess.

Monday, 09 July 2007 14:15:03 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Friday, 29 June 2007

I've touched on this before, but I'd like to expound some personal theories (or preferences) on exception handling in C#.  There are plenty of things to debate here, but this is what I believe.

There are a few assumptions I make about code to which these exception handling rules apply, and I'll try to make those assumptions evident as I go along.

  • Method names are verbs.  I'm big on verbs and nouns in code (which, I recently learned, makes me a fan of "Domain Driven Design").
    • If my method is supposed to transfer money from one back account to another, it should be called Transfer
    • If my method can't fulfill it's contract (in the form of it's verb) it should throw an exception.  If Transfer can't transfer, it should throw an exception.  Period.
      • Don't worry about whether the error is really "exceptional".  If it was really exceptional, you wouldn't catch it (see below).
  • Catch only exceptions you know how to handle, and be specific.
    • Don't catch System.Exception.
      • If you don't know ahead of time what the exception is going to be, you don't know how to handle it, and you should send it up the stack.
      • Catching System.Exception means trying to deal with the really exceptional case, which by definition you can't plan for.
  • Write your own application specific Exception classes, and write lots of them
    • Make exceptions as specific as possible
      • if I'm writing Transfer, and there isn't enough money in the source account to fulfill the request, throw an InsufficientFundsException, not ArgumentException or ApplicationException, or InvalidOperationException.
    • Hide implementation specific exceptions by wrapping them in custom exceptions.
      • If you are writing a configuration system, and in your initialization routine you look for an XML config file, and that file isn't there, don't throw FileNotFoundException.  Wrap the FileNotFoundException in your own ConfigurationInitializationException.
        • The consumer of the configuration system doesn't care about your config file, they just care that you failed to initialize.
        • The ConfigurationInitializationException should be part of your contract to the outside world, and they should plan to catch that, not FileNotFoundException.
        • If you change the config system to initialize itself from the database instead of an XML file, and the database isn't there, your consumer doesn't have to worry about DbNotFoundException, just your custom exception according to your contract.
    • Make your custom exceptions part of your contract
      • In Java, you can make that compile-time checkable.
      • In .NET, you can include the exception in your XML documentation using the <exception> element.  It's not enforceable, but at least it's documented.
    • Make sure your custom exceptions are serializable and implement the right constructors
      • VS 2005 has a template that generates good exception classes (type exception->tab)
    • There may be some very specific reasons for catching System.Exception (but I don't really believe that)
      • If you must, never catch Exception without throwing something else.
        • If you don't care if your code failed, why did you write it?  That probably points to a design problem.
      • If you find yourself arguing for catching Exception, you probably have a design problem.
        • There are real reasons for crashing your application.  If nobody knows how to handle an exception, should you really keep going?  Or just take your lumps and quit?
        • If your application writes to the database, and the database isn't there, should you keep logging errors, or just exit the application?  (This depends on how transient the problem is, etc., and I'm probably ratholing here so you get it, right?)

YMMV, but there you go.

Discuss.

Friday, 29 June 2007 11:54:55 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [4]  | 
# Tuesday, 26 June 2007

A while back I posted about how we're implementing denials using AzMan.  This week, a helpful reader pointed out that with a little extra math, I could save a call into AzMan (with all the attendant COM interop, etc.).

So, instead of my previous

 

object[] grantOps = new object[] { (object)1, (object)2, (object)3, (object)4};

object[] denyOps = new object[] { (object)100001, (object)100002, (object)100003, (object)100004 };

 

 

object[] grantResults = (object[])client.AccessCheck("check for grant", scopes, grantOps, null, null, null, null, null);

object[] denyResults = (object[])client.AccessCheck("check for deny", scopes, denyOps, null, null, null, null, null);

 

for (int i = 0; i < grantResults.Length; i++)

{

    if(((int)grantResults[i] == 0) && ((int)denyResults[i] != 0))

        Console.WriteLine("Grant");

    else

        Console.WriteLine("Deny");

}

 

I can do it in one call like so

object[] allOps = new object[8];

grantOps.CopyTo(allOps, 0);

denyOps.CopyTo(allOps, 4);

object[] allResults = (object[])client.AccessCheck("check for grant and deny", scopes, allOps, null, null, null, null, null);

for(int j = 0; j < grantOps.Length; j++)

{

    if (((int)allResults[j] == 0) && ((int)allResults[j + grantOps.Length] != 0))

    {

        Console.WriteLine("Grant");

    }

    else

        Console.WriteLine("Deny");

}

 

It does mean you have to be a little careful about getting the indexes straight, but that's probably worth the savings you'll get by not making the extra COM call. 

Every little bit helps...

AzMan | Work
Tuesday, 26 June 2007 09:12:39 (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [3]  |