www.codinghillbilly.com   kyle.baley.org  Subscribe / Contact
 
 
 
 
LATEST POSTS
Wednesday, February 03, 2010

The hillbilly be all Java’d up these days. For coming on three weeks, I’ve been the lone developer on a project based on Google Web Toolkit. It’s a web framework (naturally) that allows developers to build applications in Java and compiles it down to JavaScript, CSS, and HTML. Scoff all you want, if it were any other company behind it, I’d probably be right there with you.

We considered quite a few technologies before landing on this one. We went through Ruby, Sharp Architecture, Open Rasta, Moo Tools, and probably several others. I can defend ending up Google Web Toolkit privately if you want but putting the thought process up in a public forum is going to lead to comments that I’m too tired to moderate these days. And yes, I’ve heard of Script #, too.

Coming at this from a .NET developer’s standpoint has been interesting. It’s surprising how much we take for granted in our IDE, for example. I’m still meandering my way through the keyboard shortcuts in Eclipse (after a brief fling with IntelliJ IDEA). One thing I’d really like is a keyboard shortcut for the GWT Compile button, which currently is available only via a toolbar button or a context menu, as far as I can tell. Was happy to find a VIM plugin for it too that works as advertised.

Not sure if this applies to Java in general but within the confines of the Google Web Toolkit, the ecosystem is freakin’ phenomenal. The documentation page alone encourages unit testing and the use of an MVP architecture. Once you start reading about it, you can’t help but stumble on a number of other projects:

  • gwt-presenter: A passive view implementation for GWT
  • gwt-dispatch: A command pattern implementation for GWT
  • Guice: Google’s dependency injection framework
  • Gin: A dependency injection framework for the client part of GWT

The shocking thing from a .NET perspective is that these concepts are just sort of assumed. There’s little debate on whether dependency injection is necessary or whether passive view is overkill. Someone watched a presentation from Google IO last year, whipped up a command pattern project based on it, and lo! the people said it was good. Between support for Hibernate and the App Engine data store, I think people would look at you bug-eyed if you even suggested writing your own data access layer.

The downside to all this as that the tooling seems to be several steps behind what I’m used to in the Microsoft world. It’s still too early to make a fair comparison but even after digging a little deeper into Eclipse, I can’t imagine being quite as productive as I currently am in Visual Studio. Yes, there’s also IntelliJ but our anecdotal evidence suggests that neither Java IDE is seen as a de facto standard. For the moment, I’m sticking with Eclipse simply because all the documentation refers to it and the GWT and App Engine plug-ins for it work out of the box.

Couple of final shout-outs to two blogs that have been invaluable during the learning curve phase. First is Hive Development (currently featuring two posts on how to unit test MVP applications in GWT). Second is TurboManage, whose sample code is more detailed than many apps I’ve written.

Anyway, it’s been an interesting couple of weeks.

Kyle the Decaffeinated

Thursday, January 28, 2010

I’m imagining the thought process of some of the session voters for the upcoming Mix conference. “Hey, here’s one on Open Rasta by the Coding Hillbilly. You know what would be funny? Let’s all vote for it even though he just submitted it on a lark to get some practice after taking time out from speaking engagements. It’ll be fun watching him explain to Mrs. Billy that he *has* to go to Vegas four weeks before he’s heading to Philadelphia for Udi Dahan’s course.”

Yeah, you’re all a bunch o’ comedians, ain’t ya. Well, I’ll show you. You’ll go to my Open Rasta session ready to watch me squirm and you’ll see no such thing. I don’t want to overhype it or anything but I can tell you without a doubt that this session is going to restore your virginity and then take it from you again. Savagely (but tastefully; last thing I need is a bunch of people accusing me of statutory rape in the middle of a presentation). Then maybe next time you’ll think twice before crossing a coder of the earth, woncha!

Couple of interesting tidbits on the session:

  • Somewhere along the line, the original title got changed. I submitted it with: “Open Rasta: The REST framework MVC wants to be.”
  • I also submitted a session on S#arp Architecture. (What can I say? I’m a web framework kinda guy.) I found it interesting that the Open Rasta one got chosen and the #arch one didn’t.

So while you’re waiting for Mix, have a gander at Open Rasta to see what all the hubbub is about. Between this and my new contract using Google Web Toolkit, that should set the stage for my post activity for the next few months.

Kyle the Bastardized

Monday, January 04, 2010

I’m going to pretend a whole bunch of you have asked where the Coding Hillbilly nom de plume comes from instead of just one or two.

Though I love the name, Hillbaley Ho Down and Extravaganza, it actually reinforces a common mis-pronunciation of our last name. It’s buh-LAY, not BAY-lee. One of my resolutions this year is to enforce with military precision (though it may be based on the Bahamian military, rather than, say, Germany) the correct pronunciation. Which is something I’ve become lax with since moving to a country where I have trouble understanding the local populace's tendency to omit key parts of speech. Like verbs.

For several years, my brother and I ran a website, the remnants of which can be seen here. (I’d recommend turning your speakers off before clicking that.) It debuted auspiciously almost ten years ago under the name The Hillbaley Ho Down and Extravaganza. My brother came up with the name as a play on our last name.

The website was an absolute blast to write and did its thing for a few years until it dawned on us that very few of our family, in fact, read. But during that time, I started the technical arm of the Ho Down and used the name of the parent site as the basis for this one. But the name Coding Hillbaley would make sense only to my family who, again, don’t read. So I chose a more mainstream version.

HillbillyNext question. The avatar I use, seen at the left. This I also stole from my brother. My grandmother has this knick-knack thing she bought from who-knows-where (our money is on a Mexican border town but I shan’t elaborate). My brother took some photos of it, did some touch-ups, and voila!

The original photos of the item are below:

old_man_01 old_man_02

The nice part of the photo is how much it aligns with both the theme of my blog, my general attitude toward software development, and my family in general. Ya, he looks like a hick but damned if he ain’t having a good time. And look like he’s been into the dandelion wine.

Kyle the Ancestral

Monday, December 28, 2009

Before recently taking on my current two contracts, I flirted briefly with a position as an employee. In the end, I decided not to take the job on the grounds that they didn’t want to hire me and it made me feel better about myself to assume that everyone there is just a bunch of big jerks and I wouldn’t have liked it anyway. As a hint for you job seekers out there: when they fly you in for a three-hour technical interview, you really should bone up on your basics.

What made this a blog-worthy journey was the thought process I went through while I was still a potential candidate. After six years as a consultant, was I ready for employee-hood?

It seems like a no-brainer on the surface. As a consultant, I enjoy considerable freedom, especially with my free time which, as I age, becomes more and more important to me. Prior to my current contract, I hadn’t worked full-time in a year and a half. Mind you, that implies I’m working full-time on my current ones but between new babies, sick older children, spousal holidays, and Xmas, that’s not accurate either. But again, the fact that I have that freedom is why I love consulting.

And because all my contracts are remote these days, I’m usually even flexible with when I work. This depends on the contract but for many of them, as long as I’m available for meetings, the rest of the work can be done whenever I want. Furthermore, I can take time off for conferences or vacation almost whenever I want. I say almost to account for times when the client really needs me but alas, I haven’t been quite that indispensable yet.

“So,” sez you, “why give up all that and more to become an employee working 9-5 on a lower salary with 2 weeks vacation?”

“Don’t interrupt!” sez I, “I’m getting to that.”

There’s a certain fallacy to consulting that we don’t like to talk about. It’s the Hear No Evil syndrome. If we don’t talk about it, it won’t happen to us. It’s related to the “I decide when I want to take a contract” argument. In my experience, this argument is true only about half the time. Because the fact is, when a contract ends, there’s often some level of panic involved. No matter how much money you have squirrelled away to allow for this eventuality, there is always a sense of “what if I can’t find a contract when I’m ready?” Depending on how much panic you feel, you might just end up taking a contract you don’t like. This is especially true these days when the money isn’t flowing like water so much as it is oozing like pus.

Naysayers will argue that employee-ship is no more secure than consultancy. Those people are liars and, very likely, smelly. Employees can be let go, yes, but in my experience, they aren’t the first to go. At my last contract, when the hammer fell, the contractors felt the brunt, not the employees. (Well, at least not directly. The rumour mill suggests that there is a “let’s see how many quit after we introduce THIS policy” program going on there these days.) The contract before that, there was also a mass layoff. I believe a few employees were included in that but again, the rumour mill claims it was pruning talent just as much as cost.

The upshot of this is that in most cases, contractors will get booted before employees. Maybe it’s just a brief respite since laying off all your contractors is rarely a sign of growth but it’s a respite nonetheless. Anecdotal evidence aside, contracts are generally shorter than employee terms and in the end, it’s just plain stressful looking for them. Especially ones that allow you to work remotely 100% of the time. So the prospect of being relatively secure (judging from the effort put into hiring process, the company was one that put a lot of value in its talent) in a position that promised interesting work and still allowed me to work remotely did hold some appeal. Maybe it’s a false sense of security but there’s a reason we still don’t know how placebos work. Perception is a powerful thing.

That said, I’d by lying if I said I didn’t feel a sense of relief when they said they weren’t interested. As much as I freak out when work isn’t handed to me, I’ve been eerily lucky in my consulting career. Even when lengthy involuntary breaks do come (the longest to-date being four months), it ends up leading to more interesting work in the long run because of what I work on and blog about in the interim. As a case in point, one of the contracts I’ve grabbed now is a direct result of my involvement with Sharp Architecture, which, in turn, followed from my delving into MVC two years ago when I was “between contracts”.

I’ve been careful not to explicitly say “being a consultant is better” because I’m almost positive the roundabout way I’ve arrived at the current point in my career is atypical. But here I am and all I can say is that after going through the reflective exercise, I have to conclude that luck was once again on my side when the employee-ship opportunity passed me by. Maybe I’m on borrowed time because I do know a couple of excellent consultants who are actively searching for work (ping me if interested) and in markets that have traditionally been very lucrative, both with the type of work and in the compensation. But until then, it’s time to stop yakking and get back to billable work.

Kyle the Unemployee

Friday, December 18, 2009

Gonna delve away from CodeBetter tradition into more of the realm of our sister site, Devlicious. I.e. This post will be about code, not about thinking about writing code. Having gone through this monstrous exercise though, I gotta say, Ivory Tower Architect is looking like a mighty fine role these days.

I’m working on a search interface that uses NHibernate to search for people using various criteria, such as Languages Spoken (generally a zero to many relation), Special Skillz, and Preferred Side Dish for Various Roadkill. It uses HBM files and a couple of the collections on the Person object are mapped as composite-elements, like so:

    <class name="Person" table="People">
    ...
        <bag name="SpecialSkills" table="Mad_Skills">
            <key column="PersonFK" />
            <many-to-many class="Skill" column="SkillFK" />
        </bag>
    ...
        <bag name="PersonalHygieneMilestonesReached" table="Personal_Hygiene">
            <key column="PersonFK" />
            <composite-element class="PersonalHygiene">
                <many-to-one name="HygieneAction" column="HygieneFK" />
                <property name="LastPerformed" column="Date_Last_Performed"/>
            </composite-element>
        </bag>
        
    ...
    </class>

This is just a representative sample. The Person class has a collection of Skill objects (accessed via a property named SpecialSkills) as well as a collection of PersonalHygiene objects (mapped via the PersonalHygieneMilestonesReached property). The PersonalHygiene object contains a HygieneAction object (which is just an ID and Description) and a DateLastPerformed property.

In the search interface, we'd like to search for people who have, say, bathed. (I'm ignoring the date last performed to avoid muddying the wa--err...clouding the issu---ummm, complicating things.) So the search interface gives us a dropdown list, the user selects “bathed”, and our NHibernate-based data access class goes on its merry way.

public IList<Person> FindByPersonalHygiene( int PersonalHygieneId )
{
    var query = DetachedCriteria.For<Person>( )
        .CreateAlias( "PersonalHygieneMilestonesReached", "hygiene" )
        .Add( Property.ForName( "hygiene.Id" ).Eq( PersonalHygieneId );
    return query.GetExecutableCriteria( Session ).List<Person>( );
}

Similarly, here's how we could find everyone who has a given special skill, say, "Converses at a Third Grade Level.":

public IList<Person> FindBySpecialSkill( int SpecialSkillId )
{
    var query = DetachedCriteria.For<Person>( )
        .CreateAlias( "SpecialSkills", "skill" )
        .Add( Property.ForName( "skill.Id" ).Eq( SpecialSkillId );
    return query.GetExecutableCriteria( Session ).List<Person>( );
}

All well and good and does what we want. It’s slightly different than searching on a property of the Person object in that we are searching for the existing of an item in one of its collections. Hence, the use of CreateAlias.

The next task: Add the ability to apply multiple filters to our list of people. If someone matches ANY of the supplied criteria, they are returned by the search. That is, we want to OR the criteria together.

Let's search for anyone that has bathed OR has the ConversesAtAThirdGradeLevel special skill. Luckily, there is an Expression.Or method that, in theory, should make this easy. Let's take a look at this special case before generalizing some.

public IList<Person> FindByHygieneOrSkill( int PersonalHygieneId, int SpecialSkillId )
{
    var query = DetachedCriteria.For<Person>( )
        .CreateAlias( "PersonalHygieneMilestonesReached", "hygiene" )
        .CreateAlias( "SpecialSkills", "skill" )
	.Add( Expression.Or( 
            Property.ForName( "hygiene.Id" ).Eq( PersonalHygieneId ), Property.ForName( "skill.Id" ).Eq( SpecialSkillId )
        );
    return query.GetExecutableCriteria( Session ).List<Person>( );
}

This is essentially a combination of the two queries. We need to add all the aliases up front because Expression.Or takes two ICriterion objects, not two ICriteria objects. This can be generalized as well by modifying the FindByXXX methods so that they look more like this:

public ICriterion AddAliasAndGetCriteriaForSpecialSkill( DetachedCriteria query, int SpecialSkillId )
{
    query.CreateAlias( "SpecialSkills", "skill" );
    return Property.ForName( "skill.Id" ).Eq( SpecialSkillId );
}

public IList<Person> GetPeopleMatching( SearchCriteria criteria )
{
    var query = DetachedCriteria.For<Person>( );
    var disjunction = new Disjunction( );
    if ( criteria.SpecialSkillId.HasValue )
    {
        var criterion = AddAliasAndGetCriteriaForSpecialSkill( query, criteria.SpecialSkillId.Value );
        disjunction.Add( criterion );
    }
    if ( criteria.PersonalHygieneId.HasValue )
    {
	var criterion = AddAliasAndGetCriteriaForPersonalHygiene( query, criteria.PersonalHygiene.Value );
        disjunction.Add( criterion );
    }
    query.Add( disjunction );
    return query.GetExecutableCriteria( Session ).List<Person>( );
}

Kinda messy with all the if statements and the specialized AddAliasAndGetCriteriaForXXX methods but those can be cleaned up. I switched to using a Disjunction because it allows you to chain a bunch of ICriterion objects together, rather than limiting it to two like Expression.Or does.

The reason I won't show you the cleaned up code because when all is said and done, this won't actually work. If you look at the underlying query being executed, it looks something like this:

SELECT *    -- Not really * but you get my drift
FROM Person p
INNER JOIN Person_SpecialSkills pss ON p.Id = pss.PersonId
INNER JOIN Person_PersonalHygiene pph ON p.Id = pph.PersonId
WHERE pss.SkillId = @p0 OR pph.PersonalHygieneId = @p1

On the surface, this looked correct to me intuitively. It gave me results and those people had the specified skill and/or hygiene habit.

But I noticed there were people missing in the results. Specifically, people that had either no special skills or no personal hygiene habits. Which is when the INNER JOIN assignment from my second year databases class came rushing back to me. Of course, if you use INNER JOIN, you exclude any data where there is no match between the two tables. So my little SQL statement above will include only people who have BOTH a special skill AND personal hygiene and only those that match the given criteria.

Instead, I could use OUTER JOIN. But I didn’t much like how things were starting to meld together with the aliases and the criteria so I decided on a separate approach. In essence, for each search filter, I want to run a query. Then I want to return the list of people from all those queries. I could do that programmatically, I suppose. I.e. Execute the queries, then use List.Intersect to pull them all together.

But that ain’t how the hillbilly rolls. Instead I went with subqueries. The underlying pseudo-SQL:

SELECT *
FROM Person
WHERE Id IN ( SELECT PersonId FROM Person_SpecialSkills WHERE SkillId = @p0 )
OR Id IN ( SELECT PersonId FROM Person_PersonalHygiene WHERE PersonalHygieneId = @p1 )

To achieve this, I need slight modification to my original method

public DetachedCriteria FindByPersonalHygiene( int PersonalHygieneId )
{
    var query = DetachedCriteria.For<Person>( )
        .SetProjection( Projections.Property( "Id" ) )
        .CreateAlias( "PersonalHygieneMilestonesReached", "hygiene" )
        .Add( Property.ForName( "hygiene.Id" ).Eq( PersonalHygieneId );
    return query;
}

The changes: return the actual query and specify a projection, which is fancy-Hibernate-speak for "what fields to I want this query to return?".

From here, I created the main search method:

In this case, finders is a dictionary of Func<int, DetachedCriteria> objects keyed on a SearchType enum. It's initialized elsewhere. I use it as a sort of pseudo-strategy-type thing and if you claim that it's not *really* a strategy pattern, I won't disagree because I don't care. I just know it's cleaner than using a switch statement.
public IList<Person> FindBy( IList<SearchExpression> expressions )
{
    var query = Session.CreateCriteria( typeof (Person) );
    var disjunction = new Disjunction( );

    foreach ( var expression in expressions )
    {
        var subquery = finders[expression.SearchType]( expression.Id );
        disjunction.Add( Subqueries.PropertyIn( "Id", subquery ) );
    }

    query.Add( disjunction );
    return query.List<Person>( );
}

The main method is pretty clean now. It loops through the list of all the filters the user has selected and adds an appropriate subquery, checking to see if the Person.Id is in the returned query.

Now some of you may cry foul in the name of performance or some other NHibernate feature that makes all this obsolete. To you, I say, software is a journey, not a destination.

Kyle the Tacit

Tuesday, December 15, 2009

Some time ago, I had a small crisis of conscience as I worked on an app for my dad’s company. At the time, I wondered about the long-term viability of using so-called advanced tools like NHibernate, IoC, and MVC. Specifically, if I drop dead (and it’s starting to get a little morbid the number of times this comes up in conversation, especially with my family), will the next guy they get be able to understand it? More generally, how much do I alter my coding practices to make it more palatable to someone who might be more “learning averse”.

Cut to a year and a half later and the following has happened:

  • NHibernate has become much more well-known and easier to work with. Plus the available documentation has increased immensely.
  • MVC is no longer Scott Guthrie’s side project and the only issue now is that the version I used was pre-release.
  • The company got sold and they are phasing the application out.
    Full disclosure, there is one HUGE reason I was able to ramp up quickly on the Sharp project. Rather than send me the code/database or point me to an SVN URL, he shipped me a virtual machine pre-configured. All the projects, dev tools, and configuration was done so there was none o’ this “download the latest ELMAH and stick it in this folder” and “create this IIS app” and such. Just “here’s your VM. Go install VPC”. Granted, I did spend some time converting it to VMWare because the latter is more conducive to the Kinesis keyboard I’m using (which doesn’t have a Right-Alt key). But even that was a painless process.
  • Most notably, I didn’t die

All of these add up to a reaffirmation that I did the right thing by sticking to what I do best. I got the application done that much quicker and all the tweaks I made to it over the months (which, admittedly, wasn’t that much) were made much faster than if I had, say, hand-rolled a DAL with stored procedures. At least, I perceive that to be true. And in this industry, of course, perceived performance is better than actual performance.

That’s not actually the crux of this post but darned if it didn’t make me feel good writin’ it out.

The Hillbilly has picked up a couple of new contracts and is, once again, employed. Whether or not it’s gainful employment has yet to be determined but for the last couple of months, it has been a mellower experience than my previous contract.

Part of the reason for the calmer work atmosphere is that one of the contracts is based on Sharp Architecture. In fact, it is with none other than Sharp’s creator and benefactor, Billy McCafferty, who is as gracious a host as one would expect from someone who documents his OSS as well as he does.

The other contract is similar in that it’s ASP.NET development but it’s web forms, not MVC. It contains a single project and uses Linq to SQL data models for the data access. It’s not spaghetti code, mind you. There’s a healthy dose of copy and paste and the code-behind-thingy file from the .dbml file is constantly being re-written and/or deleted at regular intervals but for the most part, it’s relatively clean and easy to work with once you get the hang of it.

I started each contract at about the same time and here’s where the title comes in. It took me less time to get up to speed on the Sharp project as it did the other one. Not because I know MVC more than web forms but because I didn’t have to spend a lot of time figuring out the project’s conventions. How does data access work? Where does the business logic go? Where do I store things on the file system? Where do I get all the dependencies?

So I got to thinkin’ about my unfounded trepidation for the previous contract. Yes, I could have dumbed it down so the next person was able to understand it. But what if the next person already had the skill set and/or the wherewithal to recognize the patterns and how to learn what he or she needed to know? I.e. what if the next person was <shudder> BETTER THAN ME?!? (And at this point, being better than me entails only that he or she recognizes that I should have said “better than I”). Would I not be doing that person a favour by allowing him or her to grow as a developer and possibly to get the work done quicker?

This is all conjecture and reeks of arguing the happy scenario to prove my point. And I’ll be damned if I’m going to reek based solely on invalid arguments. So I’ll alter my point slightly. Maybe I got lucky in that the application had a short shelf-life and we never got the chance to see who the next person was. Perhaps I acted recklessly by increasing potential long-term costs of the project. Or maybe I did the right thing by not dumbing down the software for some possible future event. There will always be anecdotal evidence to prove either side, methinks. Case in point: at my last contract, where learning new techniques was just below washing one’s hair with a cheese grater on the comfort scale, the rumour mill says all software development has ceased in favour of off-the-shelf solutions. Makes me wonder how much was spent ripping out code that was deemed “too complicated”.

So for the time being, I believe I’ve justified myself into doing what I want and how I want it, when given the choice.

Kyle the Justified

Saturday, November 28, 2009

Today’s topic is one of my favorites, mostly because it allows me to ramble more than usual: communication.

Background: The Hillbilly is on the board for his condo association. At least until the next elections (in 127 days) when I can step down. Really should resign but my daughter has been making waves of quitting one or two of her activities because they’re “too hard” and I don’t want to be too hypocritical when I say she has to finish out the year.

There is one resident who loves and lives to “communicate”. When an e-mail discussion reaches a certain length, inevitably he will be affronted enough to send a lengthy e-mail along these lines:

Coding Hillbilly as far as I am aware I have always been civil in this matter . Lord knows I have been tempted to inject the odd profanity here and there . Do not confuse my civility with some perceived right on your part to protection from criticism . You presume to tell me what your job does not consist of so allow me to enlighten you as to what it does entail . As a Trailer Park Heights board member you owe me a fiduciary duty of care to act in the best interests of the association in accordance with the covenants and the articles . For your edification the association consists of its members so that includes "me" !  I have every right to hold you to account and demand that you carry out your duty . I am not playing games as you suggest Hillbilly , I am deadly serious . Unfortunately I don't feel that you or the board are at all serious . I don't think you understand the covenants and clearly you do not understand your role as a director at Trailer Park Heights . All I have asked you to do is enforce the covenants I get the distinct impression that you have interpreted my request as little more than an annoying pretext orchestrated by me to wage a perceived vendetta against Arbuckle ; nothing could be further from the truth . As a result you continue to fail in the discharge your duty of care owed to me and to the members generally . I think the board's handling of this matter is as poor and naive as your recent choice of Arbuckle as Chairman In fact I think this board has done a pretty poor job all around and continues to be leaderless .  Basically no-one has done much of anything and the most readily apparent evidence of this is the appalling state of the landscaping . 

You have volunteered to work for the members ! Part of your job is to make sure that the covenants are complied with . If you find this to be too onerous then you should resign . What I find ironic is that I am not the person who has precipitated this conflict ; that person would be your erstwhile chairman . Arbuckle used his position as chairman to conduct his cloak and dagger renovations and was untruthful when confronted with past board resolutions and the covenants . The neglect and apathy which allowed Arbuckle to halfway complete his renovations before anyone had a clue what he was doing has forced me to have to constantly needle you into reluctant action . This is not the way it's supposed to work and the result leaves much to be desired .

In response to my email of the 25th you state that Arbuckle has provided the board with all of the requested documentation namely architectural drawings , engineering sign off and an indemnity from the insurance company (Arbuckle) . So let's examine the documents which you consider bring closure to this matter .

Perhaps we should start with the so called architectural drawings . Hillbilly you've got to be kidding me ; not even you can possibly believe that what you sent me are architectural drawings of Arbuckles renovations ?!! This is a drawing provided by the manufacturer of the sky light showing product and model specifications ! I find this representation by you to be disingenuous to say the least .

I am pleased to see that you do actually have a letter from an engineer in Tulsa dated 3rd November 2009 . Having said that , the engineer refers in his letter to some "drawings". He states that the "renovations/remedial works are constructed in accordance with our drawings #2009042 and site instructions which is structurally safe for its intended use" . It is interesting that the engineer signed off on plans which you have never seen and almost a months worth of construction has now taken place since the engineers letter was written . In other words Hilbilly you have absolutely no way of verifying that Arbuckle's finished product is what the engineer signed off on four weeks ago . I hesitate to point out that Arbuckle's engineer is not an independent professional hired by the board at Arbuckle's expense as specified in the covenants .

The document that you consider to be an indemnity is unsigned . Whilst I am reluctant to state the obvious I suppose we all realise that the indemnity is not worth the paper it is written on as long as it remains unsigned and unrecorded . In my business we like to get things signed first and ask questions later . I hope that when you get around to asking Arbuckle to sign whatever it is that you end up with he is still minded to do so . I also hope that you are going to have a "real live lawyer" look at it on behalf of the association The draftsmanship of the current document has a distinctly amateur ring to it . Three guesses who the draftsman was ?

So one out of three Hillbilly . I'd say that is consistent with your general performance . Needless to say I have found your last response equally unsatisfactory .

Hope this clarifies things for you .

No prizes for guessing his profession.

Background to the story: Another resident did renovations and the person who sent this e-mail (who I will call Socio for convenience) wanted to see the documentation he provided to us, the board. There had already been some Melrose Place-like drama so our position was for him to take it up with the owner directly. He has unresolved issues with the other owner and refused. The response that led to this appealed for some civility and said, and I’m *not* paraphrasing, “Our job as a board isn’t to act as a go-between for residents who want to play, ‘Can you tell X I’m not speaking to him?’”. Yes, I goaded him but I needed a sample for this post and didn’t feel like reliving any of his other Greatest Hits.

Here’s where the communication lesson comes in. E-mails sent in this tone of voice have led me to apply a complex formula to determine whether or not I need to respond. The simplified version is thus:

  • Remove all statements related to pompousness or peacocking. A big indicator for this is a lack of contractions. I blame Star Trek for this.
  • Remove statements intended to show off the writer’s self-presumed mastery of vocabulary. Examples: precipitated, fiduciary duty, and erstwhile. As a general rule, I often discount any e-mail that contains the word “edification” as it is a clear signal the writer is trying too hard.
  • Remove lecturing statement and statements that sound like a parent admonishing his child for getting his shoesies all dirty
  • Remove snarky attempts at digs and sarcastic closing statements (and generally speaking, any statement that begins “hope this”)
  • Remove misdirections and misinterpretations (e.g. that lack of profanity == civility)

After pruning, divide the remaining content but the total content. If the result is less than 20%, the entire e-mail can be safely ignored.

Now to be clear, I have been known to be somewhat verbose from time to time on this blog. But that’s where the crux of the communication lesson comes in: know when and, especially, how to ramble. By and large, I violate these rules for entertainment purposes. It’s part of the overall feel I’m going for with my online persona. I throw big words into my posts once in a while usually because I think it’s funny. (Notice I didn’t say “invariably” there.)

But something like this is meant to be taken seriously. And as I read it over, I can’t help thinking it’s borderline masturbatory. Like it’s some sort of closing argument for a trial. Given that the original request was for documentation to see if he wanted to take further action, I can’t see anything actionable in it. I can’t quite figure out how he wants us as a board to react to this. He’s voiced his displeasure but using such a condescending tone that it’s easier just to dismiss him as someone who is never going to be pleased.

What’s worse is that on the odd occasion an e-mail like this does contain a valid point, it’s going to get lost in the language. To Socio’s credit, he has indeed brought up a valid concern about the landscaping recently. And further to his credit, he has historically been extremely valuable to the community for his past work in managing the landscaping on the property. But it’s too easy to dismiss this past work and any other valid concerns because of the means by which he delivers the message. Call it the Michael Moore Syndrome.

To me, a much more reasonable response would have been about a third the length and gotten right to the point. Something along the lines of “I don’t believe this documentation is sufficient to protect the board’s interest and here are the reasons why” followed by, and this is important, pointed suggestions on what you want to happen. Unless you’re practicing to run for public office, posturing like this for six or seven paragraphs serves no purpose except to set yourself up as a pariah that is “fighting against an unjust bureaucracy.”

The medium is also at fault. Certain people take their written communication very seriously, especially when they think they are better at it than most people. I was very guilty of this in my 20s when I liked to send potshot-laden e-mails to companies that had wronged me. Even now, it’s still my first reaction and I have to write a couple of drafts before I’m happy that I’m not going to make things worse.

Knowing your audience is also key. The board members are volunteers, working as a group for the benefit of all residents to the best of their ability. (At least, that’s what I assume. I get the impression that some people think people join for some ulterior motive, though I can’t figure out what ulterior motive there could possibly be. There’s little personal satisfaction in it.) If we were paid, perhaps there would be some cause for indignation like this. But since we’re all pretty much on equal footing, my first reaction if I had a concern would be to try to work with the board to resolve it, rather than set up a confrontational stance.

This probably isn’t a good time to mention that my condo is for sale…

Kyle the Communicable

Wednesday, November 25, 2009

I’d apologize for MY lack of posts lately but something tells me it didn’t adversely affect your life. I do have reaSONs that I WAS going to mention but again, I suspect no one lay awake at night thinking, “I wonder if the hillbilly has unleashed a new rule of thumB OR Not.” Suffice it to say, I did feel a little shamefuL AS The WEEKs went by but now it’s time to dust this little sideshow off with a quick PSA.

The CI server at http://teamcity.codebetter.com continues to thrive and somehow, I’ve indirectly inherited the mantle of “Project Setter Upper”. Probably because I have a lower tolerance of having the requests sit in my inbox than everyone else on the list.

When a request does come in, it doesn’t take long to set up. And it’s always a nice feeling when I click Run for the first time and everything comes back green. Alas, that happens probably less than half the time. The errors are often minor and have to do with configuration or some other little tweak. Generally, I just scan the log file, make the requestor a project admin, and punt it back to him or her to fix.

One of the most common errors is a missing assembly reference and invariably, it’s because the project is making assumptions of what’s installed on the server. So this PSA is to let everyone know what actually *is* installed on the server, which is, by and large, nothing.

That’s an exaggeration, of course. TeamCity comes with versions of various build tools and we have the .NET framework and Git, SVN, and Ruby. I believe that’s the sum total of it though. These are required in order for TeamCity to do its job. If your project relies on some library that isn’t part of the base .NET framework, we generally prefer NOT to install it. This includes things like NUnit, Gallio, MSTest, DataDude, SharpLib, mocking frameworks, etc, etc, and so on and so forth. Our rule of thumB is to keep the build server as clean as possible. With over thirty projects on there, and as varied as they are, the fewer pieces we have to manage, the better. Plus, the point of a CI server is to mimic a client machine as much as possible and installing Visual Studio in order to run a build process doesn’t meet that criteria.

To get around this, we ask project administrators to include whatever libraries they need in their source control systems. I.e. if you need to run NUnit tests, then include NUnit in your source control system somewhere.

Now, I don’t want to get all politikal, but this can get a little cumbersome when it comes to Microsoft’s dependencies. I’m sure there are others that don’t allow them to be included in your source tree but in my experience setting up these projects, it has been things like MSTest, DataDude, TFS, and XNA that have been the most troublesome. (While I’m bashing, we’ve had issues with accessing code on CodePlex as well a couple of times so if you have a choice and are thinking of using our server, I recommend some other provider for source control. CodePlex seems pretty good at managing everything else.) Bottom line is: We don’t want to install any version Visual Studio on the CI server.

That said, there are exceptions. We do have SQL Server Express 2008 on it (can’t remember if we allow user instances, though I imagine that would be all we allow.) So feel free to plead your case.

And if anyone from JetBrains is reading, I’d LOVE to have a way to create a custom landing page for TeamCity, assuming it’s not already possible (and doesn’t require knowledge of JSP). So we can put the request instructions as well as an abridged version of this post on it.

Kyle the Unsleeping

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 (9) dasBlog (12) Development (16) DevTeach (4) Domain (2) Environment (4) Estimating (1) Featured (14) Flamingo (10) Games (1) GWT (1) Hardware (6) Java (1) Javascript (7) Linq (2) Livelink (6) Lucene.NET (2) MbUnit (1) Metrics (1) Miscellaneous (23) Mocking (3) 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 (2) Software (11) Sundry (17) TDD (18) 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