Tuesday, June 16, 2009

Perpetual Re-Education: LINQ, JQuery, EF and ASP.NET MVC

I recently reconnected with a developer friend and former colleague of mine who asked what new technology I'd been playing with. I promised him I'd send an e-mail with some good links and such. After writing up a quick e-mail summary for him I realized that the guts of it were probably blog-worthy (though not particularly durable given how fast things in evolve these days). Anyway, what follows is my e-mail to him. Let me know if I missed any obvious resources or must have reference materials.

LINQ:
LINQ is a huge part of .NET 3.0, not just some dime-store novelty. LINQ is Microsoft’s (IMHO excellent) attempt at adding a functional programming paradigm to the existing .NET languages. Of course LINQ is a huge topic so if there’s only one aspect of it that you examine in detail I would say that you *must* check out LINQ-to-XML. You’ll never want to do DOM/SAX again. I highly recommend the MSDN primer on this. It’s not as long as it seems and covers everything you need to know to dive in. On top of all that, I think LINQ-to-XML is a great illustration of the underlying concepts of LINQ (and functional programming) and will help you to get your head around LINQ as a general-purpose tool.

Of course there’s also the full LINQ-to-XML documentation on MSDN. (Though I think that MSDN docs are sometimes better as a reference than a tutorial/learning tool.)

For an excellent (and thin) tutorial-like approach to learning LINQ I highly recommend the O’Reilly book “LINQ Pocket Reference” by the Joeseph and Ben Albahari. You’re not going to find a more thoughtful, well-written and concise book on LINQ. It’s actually excerpted from their other O’Reilly book “C# 3.0 in a Nutshell” which is also excellent and refreshingly thin (without leaving glaring omissions or glossing over the important parts). So if you’re looking for a good general book on the full range of C# 3.0 features you can skip the “Pocket Reference” and just get the “Nutshell” book instead. As a huge added benefit, the authors have written an excellent (and free) utility called LINQPad that’s basically a cute little LINQ statement/expression work surface. Actually, it’s a full-on C# scripting environment/”snippet IDE” that you can use in all sorts of clever, non LINQ-specific ways. Google “linqpad” for ideas and examples on how people are using it. I can’t say enough good things about the Albahari brothers’ books and LINQPad. In fact, they have a paid version of LINQPad that adds auto-completion. I love the tool so much and find it so useful that I went and bough the upgrade to show my appreciation (though as an aside, the auto-complete feature is really nice, and well worth the $19).

JQuery:
Not much that I need to say here since I know that you share my JavaScript enmity and have already been looking at JQuery. I’m glad Microsoft is embracing the technology and baking it into everything since it appears we’re stuck with JavaScript for a long time to come in our increasingly AJAX-ified world (don’t get me wrong – I love rich, AJAX-enabled web apps, I just wish we could do it with something other than JavaScript). Anyway, my only recommendation here is the Manning "JQuery in Action" book. This is a solid, straightforward introduction to JQuery without a whole lot of fluff. It’s not a reference by any means (I don’t think that’s the intent with the “… in Action” books) but it will get you ramped up very quickly on the JQuery approach and does a great job of really explaining the fundamentals. I think they’ve now got an “early access” version of the 2nd edition of this.

ADO.NET Entity Framework:
I know you’re already up on this one but I thought I would just throw a couple things out there to look at. First off, I wouldn’t recommend the Manning “Entity Framework in Action” book. I know I just said glowing things about their JQuery book, and it’s only fair for me to point out that it’s still an “early access” (read “unedited draft”) version but even that doesn’t make up for the confused meanderings of the text. There are bits of good stuff in there, but it’s just not worth the price of the book. If my opinion changes substantially with subsequent updates I’ll let you know. [As a complete aside, I really do like the Manning Early Access program. It lets you buy inexpensive, pre-release PDF versions of their books and then get updates as material is added.]

If you haven’t already you should definitely check out Stefan Cruysberghs’ series of blog posts on the EF. He’s got a bunch of really interesting, sophisticated stuff in there that will get you thinking about how to use the EF including querying and extending metadata, LINQ-to-Entities and his .AsHeirarchy() extension method (along with some insights on using LINQPad).

Of course, there’s also Julie Lermans’ blog, though I’m sure you already know about that since you’ve got her book.

I highly recommend the EF Extensions library and corresponding blog by the author. There’s a bunch of really useful stuff in there and the code is rich with EF tricks.

Also, I don’t know if you saw this update on the ADO.NET team blog, but here’s a peek at some of what’s planned for the EF in .NET 4.0.

ASP.NET MVC
Last, but certainly not least, is ASP.NET MVC. This is a huge topic but well worth the time. If you’ve been doing WebForms development for a long time and/or haven’t ever trafficked in the MVC approach then this whole thing can be pretty mind-bending, and hard to even get started with. So instead of throwing a bunch of stuff at you and confusing you even more I’m going to make just one recommendation to get you started. Buy the Wrox book “Professional ASP.NET MVC 1.0” by Rob Conery, Scott Hanselman, Phil Haack and Scott Guthrie. These are *the* guys for all things ASP.NET at Microsoft and this is hands down the best (and briefest) book on the subject I’ve seen. They do a great job of covering a lot of ground in a small book without missing the important parts. Best of all the first chapter (which is really about 1/3 of the book) is a Scott Guthrie’s NerdDinner tutorial which walks you through the creation of a full ASP.NET MVC app from start to finish. This is probably the best way to get your head around the conceptual underpinnings of MVC *and* will give you plenty of good technical detail as well. I cannot overstate how good this book is (coming from someone who doesn’t buy that many technology books, despite what you might think from reading this e-mail).

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it

Friday, May 22, 2009

Some Remarks on Comments

I was recently having a conversation about the perils of commenting code with someone and had one of those "I can't believe that I'm having this conversation *yet* again" moments. It seems a little sad to me that there are still so many professional developers out there who are baffled by the idea that a bounty of comments is anything other than utterly wonderful. I don't know if this is from a lack of exposure to new ideas, laziness, aversion to change, diet, childhood trauma, or what, but I do wish for everyone's sake that people would at least acknowledge the very real risks that come with excessive commenting. I'm not militant about this. In fact, as with most things, I would say I'm a moderate and a realist. But no matter your personal opinion, I feel as though we collectively should be beyond the hyper-simplistic attitude of "comments good, no comments bad".

The conversation ended in a stalemate (though I hope I at least raised their awareness a bit), but it did get me to thinking and I realized that I should post my boilerplate commenting guidelines that I've distributed in one form or another to my teams in the past. This started out as an e-mail to a colleague many years ago and has been tweaked and recycled numerous times to suit the circumstances. It still reads as a bit of a rant, but pretty much sums up my attitude about comments and where I think they fit in the grand scheme of things.

The 5 Risks of Code Comments

1. Contribute to codebase bloat: Guidelines for when to provide inline comments are, by their very nature, subjective. Developers tend to err on the side of "caution" in this case (for fear of being told they're not being clear enough in their comments) and comment most or all of their code (and also tend to comment out sections of code and then provide comments on why they commented out the code.) This inevitably results in severe codebase bloat. A past client of mine had a mission-critical VB/COM/ASP legacy application that was almost 1,000,000 lines of raw source -- of that nearly 20% was comments.

2. Create unneeded maintenance overhead: When inline comments become the norm, developers end up being responsible for not only maintaining the codebase, but also the comments that accompany them. Inevitably, this results in two contradictory outcomes: 1. Productivity loss for developers who earnestly try to scour the code for comments that need to be updated to match the code changes that they just made and 2. Comments that conflict with the code because they haven't been kept up-to-date, either because developers didn't have the time/inclination to do it or because they didn't realize that there was a comment that related to the code they were changing. This happens frequently when comments at the top of a long method apply throughout – another developer may not even realize that the bit of code they’re working on has a comment that applies to it (as an aside, this is yet another argument for the "concise method" philosophy as well).

3. Create and perpetuate confusion: Comments don't compile. No matter how concise and explicit you try to be with your comments, they are NOT definitive. Only the code compiles, so in the end the code is the only thing that is meaningful in any absolute sense. For the comments to be as concise as the code, they must (inherently) be both as structured and as specific as the code itself. Because they don't compile (and therefore cannot be logically validated) this is obviously not a realistic approach to inline comments. Consequently, inline comments will always be more abstract/generalized than the code itself, or put differently, the code will always be the specifically accurate and definitive expression of application behavior. In the presence of simple, thoughtful, well implemented code using agreed upon standards and conventions specific comments will only serve to create confusion about the code that they refer to (And besides, do we really need the comment "// Checks to see if x is 0" for the line of code "if( x == 0 )"? ) The only exception to this is the practice of identifying exceptional situations and implementations. This case is where the developer intentionally and thoughtfully chooses to deviate from the conventions, standards and best practices for a specific reason (for example, refactoring to a less maintainable but higher-performing implementation to address a performance issue.) In this case, an inline comment stating that the developer chose the particular implementation instead of using the standard approach intentionally and stating *why* this decision was made creates clarity by identifying the section of code as exceptional in some way. This is exactly opposite of the normal approach of commenting everything - by only commenting exceptions you are creating clarity about the stuff that *isn't* commented. You're saying "Hey everyone, this other stuff follows the rules and patterns that you already know."

4. Encourage sloppy implementation: The ability to comment on one's code encourages the mindset of "justifying" bad implementation. For some reason, developers tend to think its ok to write bad/sloppy code as long as they acknowledge it. By forcing the developer to express themselves solely through concise, well-crafted code the temptation of explaining away bad practice is removed and the resulting code is, consequently, of higher quality.

5. Give credibility to excessive complexity: Ultimately, inline comments create major complexity for minimal or no value. Our philosophy is that a strong shared understanding of the functional metaphor by the developers, combined with a simple, straight-forward architecture and strong coding standards more than compensates for a lack of inline comments intended to provide "context". To provide non-specific (i.e. semantic) context we have a much more powerful tool available to us in the form of Xml comments at the member/method level (in fact, they even sort-of compile because the format can be validated for well-formedness). If these, combined with an understanding of the behavioral metaphor, expressive naming, and simple, concise code don't provide enough information to understand the implementation then the implementation itself has become bloated and should be refactored to a simpler form. This simplicity not only improves the ability of developers to understand the code but also to maintain and enhance it.

In summary: In-line comments are more trouble than they're worth. In place of these are the following practices:

Code Commenting Best Practices

1. Simple, concise code and an all-pervasive mentality of refactoring whenever we notice things getting too complicated to understand.
2. Expressive naming of variables, methods, etc.
3. Method/member level Xml comments that explain the overall semantics of the method/member.
4. Appropriate use of the standard MS "intelli-comments":

  • // HACK: Improper/shortcut implementation to be fixed ASAP. Allows a developer to prioritize the specific pieces of implementation but NOT allowed to go into production!
  • // TODO: A placeholder. No current implementation for this piece of functionality.
  • // UNDONE: Implemented but functionally incomplete. Needs more code.
5. Deliberate and restrained use of the "exception to the rule" in-line comment. This is the "I'm calling out this one specific bit of code because it's exceptional/doesn't adhere to our standards/is performance tuned in a non-obvious way/etc. and someone looking at this code in the future will need to know that I did it deliberately, and why." Use the "intelli-comment" like syntax "// NOTE:" to indicate that you intend this comment to live with the code.
6. Comments on source-control commit to associate a specific change event with the reason for that change.
7. If it's a comment and not part of the above - ask the person who wrote it (yourself or someone else) why it's needed and if that purpose isn't better served by a combination of the above practices. Then fix it. Comments can be refactored too!
8. Always end a comment with your initials. This serves two purposes: 1. It makes it easier for others to know who to go to if there's uncertainty about the comment (without having to go back to commit history in source control) and 2. Having to stand by our comments forces us all to be thoughtful about whether or not a comment is really needed in the first place.

I think this pretty well summarizes how I feel about comments but I'm curious to hear what folks have to say.

References:
In response to the above my pal Mark W. pointed me at this excellent Tim Ottinger article "A Comment is an Apology" which is a different take on the subject with the same basic message. Thanks Mark!

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it

Thursday, March 26, 2009

How to NOT use XSD.EXE

I've never been a big fan of xsd.exe. It always felt kinda crude and clunky to me. No support for properties - simple type elements are public fields, limited control over name mapping, a bunch of other minor quirks and not so minor irritations. All of these complaints, when combined with the simple fact that it was a little documented, closed-source command-line tool added up to a less than spectacular solution. Up until now, however, it's worked (sort-of) and really been the only game in town for free xml-schema-to-.NET-classes code generator.

Recently I was working on an integration project. I'm sure you've heard this one before: REST-y web services consumes XML and does wonderful things with the XML behind the scenes. The business logic involved in handling the raw XML and doing all the right stuff was extremely complicated and everything (not the least of which my unit and system tests) we're getting lousy with XML manipulation code. It was pretty clear that I needed something strongly-typed and class-based that I could work with in my code (while still being able to effortlessly hydrate and de-hydrate) XML.

[ed. Note: as an aside, if you're a .NET developer using 3.5 and you're still doing your XML handling using XmlDom you really owe it to yourself to stop reading this blog post right now and go read the MSDN primer on LINQ to XML (http://msdn.microsoft.com/en-us/library/bb308960.aspx) I'm sure you're probably tired of all the LINQ hype by now, but frankly (and especially in this case) it is *entirely* justified. Once you've started using LINQ to XML you will strenuously avoid any other approach to reading, writing and querying XML. It's really that good.]

So here I am needing to generate .NET classes from my XSD. The funny thing is that my first instinct was to go hunt for a new tool to do this. I hadn't needed the services of xsd.exe for a long time and I was thinking to myself "Surely there *has* to be a new and better tool now." I was surprised and more than a little disappointed to find (after a *lot* of research) that aside from the usual smattering of exorbitantly priced commercial software there had been shockingly little progress with and not even much discussion about this particular subject. Everyone was still talking (and complaining) about xsd.exe.

At this point I'm simply resigned to using xsd.exe and moving on with my life. This is where things get a little weird. Apparently, there hasn't been a new version of xsd.exe since .NET 1.1. Well that's a little weird, but ok. I'll just go and find the SDK directory under… oh, wait, this is a new machine that's only had VS '08 installed. Well in that case I'll just go and grab the binary online, it shouldn't be too hard to find. [Three hours later…] Finally, I've got the xsd.exe binary. Now just run it and… "This program requires that you upgrade to the Microsoft .NET Framework Version 1.1" What?! Gahhhhh! Back to Google. (As an aside, I have no clue what's going on here and haven't had a chance to research it. I looked in \Microsoft.NET\Framework\v1.1.4322\ and all that's in there are gacutil and regsvc config files. Also, I see that in VS I have only 2.0, 3.0 and 3.5 as possible framework targets. Apparently .NET 1.1 doesn't install with Vista?)

Anyway, this is way more preamble than I intended for this post (though I'm really hoping to save others and "Future Jake" the pain I suffered around this particular issue (and the substantial lost time trying to sort it all out). So to make an already long story just a bit longer. I gave up on xsd.exe (which I really didn't want to use anyway) and re-doubled my research efforts. I have to admit at this point I was considering writing something myself, even though a recent experience with generating *documentation* from XSDs had made it really clear that this would've been a *serious* undertaking.

I really didn't expect to find anything more, but I tried. I don't know what new search term I used or link I clicked on that I hadn't the first time around but here's the breakthrough I made.

Daniel Cazzulino (an excellent and prolific blogger some may know as Kzu) posted a blog entry way back in October of 2003 that talks about the limitations of xsd.exe (specifically the public/settable nature of the members in the generated classes) and discusses the little-known and poorly documented in-built support in .NET for XSD-based code generation using the XmlSchemaImporter and XmlCodeExporter from the System.Xml.Serialization namespace. This approach requires shockingly little code and is, apparently, how xsd.exe does its code gen.

Here's that original post: http://www.clariusconsulting.net/blogs/kzu/archive/2003/10/24/96.aspx

Then, in a May 2004 post Kzu continues this conversation with an adaptation of the technique to turn his code generator into a VS.NET custom tool. http://www.clariusconsulting.net/blogs/kzu/archive/2004/05/14/XsdCodeGenTool.aspx

Note that the link to the code download on gotdotnet no longer works (since gdn is now dead).

It ends up that Kzu re-worked these blogs into an article for MSDN, complete with full source, later that month (May of 2004). http://msdn.microsoft.com/en-us/library/aa302301.aspx

The source: http://download.microsoft.com/download/5/E/9/5E923D54-242B-48F4-B3A1-DA8CDED6BE45/XsdGenerator.exe

Although it's relatively old (in Internet years) it's still an excellent article and a valid (*the* valid?) approach for XSD-based code generation in .NET. I used this instead of xsd.exe with great results (and this was a pretty complex schema set). It wasn't perfect. The output shows it's age a bit - no nullable type support, arrays instead of generic lists, and a few other minor quirks - but it worked for me "out of the box" with .NET 3.5 SP1 and the output was usable in it's raw form (ie. No post-generation tweaks required that later have to be manually diff-synced when you change the schema and re-gen, a major plus).

Anyway, just today I stumbled on a new (2009.01.27) project by Pascal Cabanel on CodePlex that references Kzu's article and cites it as the author's inspiration. Apparently, he's adapted the technique (and updated it) to produce a more rich, business-object type output. I haven't played with it yet, but it looks very promising. Updates once I've had a chance to try it out.

Pascal Cabanel's Xsd2Code: http://xsd2code.codeplex.com/

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it

Monday, March 16, 2009

US Census as Test Data

Turns out that the US census is a very cool source for test data. For example, the census results from 1991 contain all first and last names with information on how common they are. I'm sure there are other useful pieces of data in there too.

Best of all it's free (or more to the point, you pay your license fee every April 15th).

Refenence:
US Census Data

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it

Self-Signed Client Certs

When using self-signed client certs (for example testing TLS from a browser to your local dev server) be sure to add it to the “Local Computer => Trusted Root Certification Authorities” store AND the “Current User => Personal” store. Once you do this it will show up in IE/Firefox as an available client certificate and IIS will accept it as valid/trusted.

Also, IIS7 has a built in self-signed certificate generator for server certs in IIS admin. Long overdue.

Lastly, if you ever need to get at the thumbprint of the client certificate in ASP.NET, here’s the code:

if( Request.IsSecureConnection )
{
X509Certificate2 certificate = new X509Certificate2( Request.ClientCertificate.Certificate );
Response.Write( "X.509 Thumbprint = " + certificate.Thumbprint + "<br/>" );
Response.Write( "X.509 SubjectName.Name = " + certificate.SubjectName.Name + "<br/>" );
}
References:
ScottGu's Blog
Usenet Post

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it

Knuckling Under

I've successfully resisted starting a blog for years (except for my Tweet Project blog, but that's a whole other story). I'm not down on the idea of blogging, mind you, I just never felt like I had anything to say that was so insightful that it warranted a public airing. I don't mean this in a self-deprecating way. On the contrary, I think I've got plenty of useful ideas to go around, but I never felt they were so significant that I had an obligation to memorialize them, and I don't love the act of writing so much that I just can't help myself. So the cost/benefit analysis just never quite came out right-side up for me. I know myself (and my ambivalence about writing) well enough to know that blogging as an exercise for its own sake would have a short and certain outcome in my hands. I'm honestly not being flippant, nor disparaging bloggers in general. While there is undoubtedly an abundance of mediocre (if not well-intentioned) blogs on the web there are a surprising number of excellent blogs out there, written by thoughtful, intelligent folks who are enthusiastic about sharing their unique perspective with the rest of the world. I wouldn't call myself an avid blog reader, but there are a handful that I follow regularly and countless more that have proved at least momentarily useful or thought provoking to me. Again, I don't have anything against blogging. I just never felt like I had a good enough reason to write one.

I've changed my mind.

Or maybe I've just changed the parameters a bit.

The bar on this blog is set pretty low. I'll try to use complete sentences and proper grammatical structure, but there won't be much in the way of evocative prose, deep insights, controversial political positions or flowery rhetoric. It's basically intended as a simple repository of stuff that I need to capture somewhere because it's value to me is greater than nothing, but not so high that it warrants some kind of formalized preservation (for example, having it tattooed on a body part).

I know, sounds pretty underwhelming. Let me try to explain.

In software development the first place you turn for information is the Internet. I know, I know... this is becoming increasingly true for most any subject, but it's always been true for software development, and specifically, web development. Over the years the quiet devotion and prudence of kind strangers has gotten me out of countless technology jams with little more effort on my part than a quick Google search. But honestly, aside from a sprinkling of Usenet postings way back in the day I've never been that person. Actually, even then I was generally the guy asking the questions, not answering them.

Recently I found myself in just such a situation and had a bit of a guilty revelation. Actually, in this particular case it was doubly bad because I knew that the vaguely obscure technical issue I was struggling with had previously visited my little world. This was a problem I had already solved at some point in the past and I had forgotten what the solution was. Needless to say, this situation is a little irritating and prompts all kinds of internal dialog along the lines of "Oh great, the beginning of the end... the early stages of old age. Soon I won't even know that I hate creamed corn, let alone remember how to fight off the nurse's aid feeding it to me." Of course, in retrospect I'm confident in knowing that this is the usual state of things. Developing software, like most any other human pursuit above Maslow's first-tier (and even some of those), is comprised of myriad tiny, interlocking bits and pieces of fleeting importance and sufficient complexity (both in their very composition and in the way they're wired together) that it's perfectly reasonable for an intelligent, non-Alzheimer's suffering person to forget many if not most of them. I suspect I'd be fully nuts by now if I didn't, actually.

So here I am, re-solving a problem because I can't remember the original solution, or even what I was doing when I last solved it [as an aside - this actually happens quite often but I'm able to remember the project I was working on when I solved the problem originally and I can just go troll my old code until I hone in on the answer]. Anyway, the first thing I do is jump on Google and start digging. And in this particular case, after a few minutes of fiddling with search terms and skimming results I not only find the solution to my problem in the form of a post on some random guy's programming blog, but I realize that this is the same place I found the answer the last time. I was ashamedly grateful enough that I actually posted a comment to thank him for saving me hours of trial-and-error, not once, but twice. It's important to note here that even the posting of a one-line comment is a bit unusual for me. It's not laziness, but instead that contributing in that way is just outside of my normal behavioral context. It sounds silly, but it's true. In fact, I'm convinced that it’s a pretty fundamental personality thing. A minority of people are content producers by nature and the rest of us are just consumers. The pigs-and-chickens thing as it applies to information sharing.

But here's where my revelation comes in. Writing stuff down is a potent form of remembering. Actually, it's the means to overcome our impressive, but still limited capacity to retain and share knowledge. Things would be very different if we had never figured this out. And props to the people who originally realized this because they actually had to invent writing too.

So here's the thing: capturing this stuff in a blog is a great way to ensure that it's close at hand if I ever need it again. This is true enough for simple things that didn't require a whole lot of effort to work out, but especially valuable for those times when the answer wasn't as obvious and I had to invest hours or even days driving to a solution. Obviously, it's preferable to not repeat that process as a sort of deja-vu problem solving exercise. Ultimately, taking a few moments to scribble some notes about the solution is a remarkably valuable investment. Even if it's only a small percentage of cases where I actually need that information again in the future, the potential time-savings far outweigh the cost. So from a purely self-serving standpoint it passes the cost/benefit test and is probably something I should've been doing all along. As a blog post, it reaps all the benefits of being a centralized repository of stuff that Google will at some point index, making it really easy for me to find later. Altruistically, this also makes it accessible to anonymous strangers half-way around the planet who happen to share the unique kinship with me of trying to solve that particular problem. Maybe it saves them a bunch of time. Maybe it helps them to come up with an even better solution, and maybe they post a comment about it, completing the feedback loop and rewarding me yet again for my original (and minimal) efforts. Even from the most selfish of perspectives this seems like a good idea.

Here's the thing though: I know myself well enough to know that in order for this to work I need to set the bar pretty low. I've already admitted to not being particularly inclined to written discourse (I'll talk until I'm blue in the face though…) This blog is not about good writing. This blog is going to be crafted to intentionally low standards. If I'm not on the hook for great writing then I actually stand a chance of producing something of value. So that's it. I'm giving myself permission to not worry about it. Posts will be terse. Grammar and spelling will teeter precariously on the brink of marginal. But maybe, just maybe it'll prove useful to me… or you.

This is the longest, best crafted and most thoughtful thing I'm likely to post. It's all down hill from here.

Oh, and as for the name - it doesn't mean anything. It just appealed to my right-brained alter ego. That guy doesn't get enough play so I thought I'd throw him a bone.

Add to del.icio.usDiggIt!RedditStumble ThisAdd to Google BookmarksAdd to Yahoo MyWebAdd to Technorati FavesSlashdot it