www.codinghillbilly.com   kyle.baley.org  Subscribe / Contact
 
 
 
 
LATEST POSTS
Thursday, June 25, 2009

This post is over a week in the making. I attended AltNetBeers #9 last week in London which is making a quick rise in my list of top developer-related events, big or small. And that’s not just because I got one of the best compliments ever from someone who claims his non-IT friend reads a single IT-related blog (take that, Hanselman!). Anyway, it’s nice to know I’m reaching my target audience.

The event was not altogether removed from what Sebastien outlined at the one I attended last year which shows a degree of vision to which I only aspire. We spent a couple of hours talking on a topic of choice (as voted by attendees), then socialized until the place closed down at the unreasonable hour of 11pm. I’m told much merriment ensued afterward but, after posing for a picture, I made my way back to the hotel.

The topic at hand, and I’m paraphrasing: How do we become better developers today, and how do we create them tomorrow? Nice and subjectively vague, just how I like my open spaces. The runner up topic, brownfield applications, seemed suspiciously planted so I threw my weight behind the one we eventually chose.

Kinda concerned at how often this image is relevant to my posts

Conversation ran the usual gamut from apprenticeship programs (and thanks to Neil for the extensive historical thesis into the concept) to showing passion to defining professions to just going out there and doing it. My position through most of it was to focus more on the non-technical skillz, to the point where I think I pooh-poohed actual book learning more than I should have. If you decided, based on my advice, to drop out of university, I’d advise you to politely grovel to your dean to get back in. It’s still important. But take a psyche course or two when you go back.

Alas, we didn’t offer as much practical advice to the first part of the question as I would have liked so I’m expanding on the closing comment I made. It was essentially: Follow your instincts.

Now, there’s a danger with throwing out a broad statement like this because I made it in a very specific context. Namely, in a crowd of people who had taken time out of their lives to come to an IT-related event (albiet, one with more social activities than your average code camp; it *is* held in a pub after all). These are people who, at some level, have made a conscious decision to improve themselves on their own time. They could have had much better things to do but their instincts told them that this was an event that was more important than attending the new West End show, Deliverance: The Musical. (Side note: I know I just made that up now but MAN, the Duellin’ Banjoes scene would rock live; I suspect they’d lose a lot of people at intermission though.)

A lot of people have questions like, well, how do I make myself a better developer. The fact that they are asking those questions is the first step. The next step is to trust that they can muddle their way through their own answer. Because as we proved last Wednesday night, the same answer may not work for everybody. Me? I’m not much of a book learner. Nor, ironically, do I get much out of scanning blog posts (other than creating my own internal Google index so I know where to look later when the topic becomes relevant to me).

It’s dead simple to make yourself a better developer nowadays. Resources are plentiful and mostly free. And the ones you pay for, like conferences and training courses, are easy enough to rank with a little research (e.g. JP’s Nothin’ But .NET, Oredev, NDC). All it takes is a focused effort to make yourself better and to put some thought into how you go about it. You alone know which bloggers out there speak the same language you do. And you alone know which technologies will help you in your daily life and which ones interest you. Yes, SharePoint developers are in high demand but is it a product you want to learn and spend eight hours a day working with? (That’s not meant to be facetious actually, stop laughing.)

There will be much second-guessing and wondering which way you should go. And that’s fine. I won’t pretend I’ve made the right decisions all the time but like the software we’re supposed to be writing, most decisions are reversible. Humming or hawing about a contract in Dubai? Go for it. If you don’t like it, go home when it’s done. Worried about being away from your family that long? Well, you have some soul-searching to do but once you’ve made the decision, move on to the next one.

Was it the right decision? In my experience, unless you have direct and obvious evidence to the contrary, the answer is always yes.

Like I said, the topic is generic enough that pretty much everyone’s opinion will be valid, likely because it has worked for them personally. The underlying message I want to get across isn’t so much how to improve yourself (because you already know how to do it), but rather, if you’re in the London area, AltNetBeers is not to be missed. Many thanks to Neil, Toby, Scott, Andrew, Chris (both of them), Paul, Christian, and Lorenzo for the conversations and, of course, to the incredibly humble and reticent Sebastien Lambla for organizing and chairing the event, and also to Neil Robbins for the geek lunch two days later.

Kyle the Well-Shod

Thursday, June 11, 2009

I got an e-mail from someone wondering why his ASP.NET page was getting bigger and bigger and what this huge hidden INPUT tag was in the source. I smiled knowingly and went about my reply. That’s not the reason for this post but it is the context which led to it.

If you have an iTouch or iPhone with auto-correct turned on, here’s a little typing exercise for you. Type the following two words without having to press backspace to correct them:

  • ViewState
  • RedWings1

Capitalization doesn’t matter.

If you have the same issue I have, this will be impossible. In any application, whether it be Safari, Notes, Lucky Ladies of the Ozarks, or Twitteriffic. As soon as you type “viewst”, it is impossible to press the A or D keys. Similarly, when you type “redw”, the next key can not be I or J. In order to type these words out, you must enter some other letter, then backspace to correct it. Then it will let you type the one you want.

A quick BinG/oogle didn’t provide any answers but the iridescent Scott Reynolds provided one clue by suggesting that auto-correct was the culprit, which, of course, it was. That said, I’ve never had auto-correct actually prevent me from typing anything, only suggest.

No solution for me as yet except to turn off auto-correct, which I should do anyway, given the number of times I type tunderin’. Of course, the fact that it’s trying to prevent me from typing ViewState in the first place suggests that this is actually desired behaviour.

Kyle the Touched

1Those of you who know about my knowledge of sports may wonder how I discovered this one. Easy: I didn’t. Twas the mighty @HuntJason.

Friday, June 05, 2009

To me, nothing is more disheartening than having my optimistic view of the world negated. Yes, sometimes people do irrational things on a regular basis but in the back of my mind, I always think there is a middle ground that can be achieved somehow. That hope is never lost. Or at the very least, that it won’t affect me personally. (Side note: I jest. Look it up.)

So here’s a question: What would you do if people more experienced than you were brought in to your team to work with on a project? Would you react with fear that you wouldn’t be able to keep up, or that your job was in jeopardy, or that they’d go crazy trying to implement “new-fangled” ideas like MVP? Or would you welcome the opportunity to learn and advance your craft.

What happens when they start introducing concepts that they know in their heart of hearts will make the application better but that you don’t agree with at first glance? Do you dig in your heels and violently oppose them? Or engage in a debate to come to some common understanding?

These are leading questions, obviously, and you know what my answers are to these questions. This post is more about the people, the ones that answer yes to the former questions rather than the latter above, even if they do it subconsciously.

Simply put, it’s frustrating. I’ve tried to rationalize the responses I get but the only conclusion I can come to the fits is that there are people in this world who are not only unteachable but are also steadfastly against even trying to learn. I was so sure that these people didn’t exist.

For someone who always thinks people want to do their best and always want to improve themselves and their craft, it’s depressing. Maybe I’ve just been lucky in my career that I’ve never encountered them, or maybe I’m just insulated from them because the people that I hang with, that go to or speak at user groups and conferences, are pre-inclined to the continuous learning disposition. But it’s not just in my industry. I can’t think of a single person I know well that doesn’t want to be better at what they do, whether it’s accounting, or land surveying, or nursing.

It’s not the lack of knowledge that bothers me so much as it is the close-mindedness. Listening to barely concealed sarcastic comments like “how many cool patterns can we put into this app?” Counter-arguments like “We’ve always done it this way” or “we need to be consistent with our other applications” or simply “I don’t like it.”

I can deal with disagreement. There are others on my same team that I don’t always agree with but that I respect. When we debate the merits and pitfalls of one method vs. another, it’s based on experience and rationality.

But here’s the distinction: if, at the end of these rational debates, we end up not using my method, I’m still happy with the code I’ve written. And that I’ve gained a new perspective. Being forced to go back and remove all INNER JOINs from our stored procedures because they’re “too confusing” makes me feel like I’m losing some unseen war.

And it’s one that I didn’t think even existed, let alone had to fight.

Kyle the Disenchanted

Tuesday, June 02, 2009

“Yield” is not generally a word we hillbillies understand all too well as my meanderings yesterday can attest to. I’ve been using the yield keyword for nigh on three years now while having only a vague understanding of how it works behind the scenes. And even now, I’m not quite sure where my logical fallacy is but I’m sure that over the time it takes to write this all out, I’ll have formed an opinion.

Here is a the first test I wrote for a new class:

[TestMethod]
[ExpectedException( typeof( ArgumentException ) )]
public void Should_throw_exception_if_search_term_is_not_provided()
{
    var sut = new VacationDestinationService();
    sut.FindDestinationsByRegion(string.Empty);
}

Bear with me on the ExpectedException. I’m pretty sure my problem is that I’m writing the wrong tests but for now, let’s just follow the “thought” process.

To get this test to pass, I created the following class:

public class VacationDestinationService
{
    public void FindDestinationsByRegion( string region )
    {
        if (string.IsNullOrEmpty(region))
        {
            throw new ArgumentException("C'mon, feller. You gotta pick a place.");
        }
    }
}

Of course, I don't want this class to return void in the long run, but it gets the test passing.

Here's the next test:

[TestMethod]
public void Should_retrieve_search_results()
{
    var sut = new VacationDestinationService();
    var results = sut.FindDestinationsByRegion("North America");
    Assert.IsTrue(results.Count() > 0);
}

Again, don't get semantic on me. This isn't *really* the actual test. But like most developers, I don't want to get bogged down in dependencies and explaining context.

To pass this test, I modified my VacationDestinationService accordingly:

public class VacationDestinationService
{
    public IEnumerable<string> FindDestinationsByRegion( string region )
    {
        if (string.IsNullOrEmpty(region))
        {
            throw new ArgumentException("C'mon, feller. You gotta pick a place.");
        }

        var destinations = new List<string>(new[] {
            "Ozarks",
            "Appalachia",
            "Western Manitoba"
        });
        foreach ( var destination in destinations )
        {
            yield return destination;
        }
    }
}

And lo! This passes our test. So I re-run all my tests again before checking in, and lo!:

image

“What?!” says I, “Why is the first test failing?” Reaching for the debugger yields (teehee) no help because setting a breakpoint in FindDestinationsByRegion doesn’t do anything. That is, for all intents and purposes (pet peeve: NOT “intensive purposes”), the code in FindDestinationsByRegion is not called in the first test anymore. Hence, the exception isn’t thrown. Hence, the test fails.

If you’re the type of guy/gal to dive into the IL for this kind of thing, then you may know where this is heading. From what I can gather, the yield causes this method to execute only when the results are iterated. That is, even if we call this method and gather up the results in a variable, the code still won’t execute. But as soon as you throw it in a foreach loop, then you’ve got gold, baby.

Maybe this is what smarter people mean when they throw out terms like “delayed execution”. Maybe this is the cornerstone of lambdas. All I know is that I can’t check in my code until I’ve solved this problem to my liking.

As a test for this theory, I modified the first test slightly:

[TestMethod]
[ExpectedException( typeof( ArgumentException ) )]
public void Should_throw_exception_if_search_term_is_not_provided()
{
    var sut = new VacationDestinationService();
    sut.FindDestinationsByRegion(string.Empty).Count();
}

Note the extra call to Count() at the end of the second line. Now we are not only retrieving the results, we are iterating over them. This test passes.

So what is the big picture? Is the code wrong or my tests? Assuming I *do* want to throw an exception if the argument is wrong, is the code correct? What if someone provides an empty string to this method and never iterates over the collection? Apparently, this method won't fail in that case, but that may not be a bad thing. Or it could be because then we have code that's kind of useless.

It seems to me that the test should be modified to cause the iteration to happen and force the exception. If someone wants to call this method without iterating, I see no problem with that. I don't think.

Another thing I did was to replace the yield and return the List itself. This worked too but I don't like the idea of modifying my code for what appears to be a faulty test.

Was expecting to have formed an opinion by now but it's still kind of fuzzy. I'll let it sit for a while and perhaps a solution will present itself to me in the form of a better developer fixing it.

Kyle the Iterative

Monday, June 01, 2009

This post is brought to you by the letters M and V and P. I mention that at the beginning to set the pre-requisites.

I woke up this morning, broke open our application, and am currently staring at this method in our presenter.

public void Start( )
{
    if ( !IsAuthorized( ) ) return;
    if ( !ValidateHeritage( ) ) return;

    if ( !IsCousin( ) ) return;
    if ( HasSiblings( ) ) return;
}

My first reaction to this was that it didn’t actually do anything. The way it’s currently set up, it appears to check a bunch of guard clauses and exit if they are met. But there isn’t any actual code being executed if the guard clauses aren’t met.

Digging deeper, I discovered that the guard clauses are actually doing more than guarding. They are calling methods on the View and otherwise changing state. For example, the IsCousin method:

public bool IsCousin( )
{
    if ( _user.AuntsAndUncles.Contains( _prospect.Mother ) 
         || _user.AuntsAndUncles.Contains( _prospect.Father ) )
    {
        _viabilityCount++;
        View.DisableSafetyChecks( );
        return true;
    }

    return false;
}

Clearly, this is ain’t your mother’s guard clause. It’s updating a local variable and doing some fanciness in the UI as well as guarding.

So maybe it’s just an issue with naming. Obviously, it’s not a guard clause, so maybe I could rename it to make that clearer. An obvious name isn’t leaping out but in any case, something feels wrong about having all these methods return a boolean.

An alternative I’m considering is separating the guard clauses from the actions:

public void Start()
{
    if ( IsAuthorized( ) == false )
    {
        SetNotAuthorized( );
        return;
    }
    if ( ValidHeritage( ) == false ) return;

    if ( IsCousin( ) == false ) return;

    if ( HasSiblings( ) == false ) return;
    
    IncreaseViability( );
    DisableSafetyChecks( );
}

Clearly, this is more verbose. But it looks better to me because the guard clauses don’t actually do anything except check the state of something. The actual flow of code is more obvious (isn’t it?).

Maybe the original method is fine and I’ve been reading too much on Command-Query Separation lately. Or maybe there’s an alternative. In which case, I’d love to hear it, even given the very limited context I’ve provided.

And in order to solicit as many opinions as possible, and because I know how much we all love to prove each other wrong, I’ll make the claim that my alternative is THE DEFINITIVE way of doing this.

Kyle the Reversed

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Copyright © 2010 Kyle Baley. All rights reserved.
 
CATEGORIES
.NET General (18) alt.net (4) altnetconf (9) ASP.NET AJAX (40) ASP.NET MVC (29) Bahamas (1) Bahanet (9) BDD (1) Brownfield (18) Career (9) Castle (1) Code coverage (1) Coding Style (6) Communication (1) Community (18) Conscientious Coding (34) Continuous Integration (11) dasBlog (12) Development (16) DevTeach (4) Domain (2) Environment (4) Estimating (1) Featured (14) Flamingo (10) Games (1) Google App Engine (2) GWT (5) Hardware (6) Java (1) Javascript (7) Linq (2) Livelink (6) Lucene.NET (2) MbUnit (1) Metrics (1) Miscellaneous (24) Mocking (4) NAnt (4) NHibernate (12) NInject (1) Office (3) Office Development (6) Open Rasta (1) Patterns (5) Presenting (13) Professional Development (15) Refactoring (10) ReSharper (11) REST (2) S#arp Architecture (5) Security (3) Software (11) Sundry (18) TDD (19) Tools (21) User Interface (5) Utilities (8) Visual Studio (8) VSTO (1) Web development (12) Windows (3) Working Remotely (16) Workplace (3) Writing (4)
 
LATEST POSTS
 
POPULAR POSTS
 
 
ARCHIVE