www.codinghillbilly.com   kyle.baley.org  Subscribe / Contact
 
 
 
 
LATEST POSTS
Wednesday, November 28, 2007

Day 1, for completeness, I spent shopping with Dave Woods, which he really should hire himself out for as a service considering how often he does it. Also saw No Country For Old Men (review, such as it is, is over at my usual movie haunt; short version: it rocks) and attended Party With Palermo and we now have undisputed, non-Photoshopped proof that Justice Gray and I are two different people.

Summary sessions I will leave to others because as it is, this post will be lost in a sea of DevTeach: Day X blog posts. Instead, here are my reviews of the presenters' styles. No links to their blogs because they're pretty much all more well-known than I am.

Jeremy Miller: How does design get done on an Agile project?

Presentation alias: The Story Teller (no pun intended...ok, it was intended)
Underlying motif: Down-home folksy; free and easy going
Summary: Watching Jeremy present is kind of like talking with your older brother whose just come back from a trip to Europe and has some good stories to tell. Any advice he gives seems as if it has been passed down for generations.

Donald Belcham: Continuous Integration with CruiseControl & NAnt

Presentation alias: Pipes
Underlying motif: Understated; commands respect
Summary: Don, with his low, resounding voice, is the Barry White of presenting. Everything he says sounds like it will help you, personally, get laid. You could hear audible swooning from the audience whenever he said "continuous integration, baby".

David Laribee: User Stories, Iterations, and Releases

Presentation alias: The Hippie
Underlying motif: Approachable and affable;
Summary: Dave is the master of fonts and presents with a bit of an edge. He's got a quick wit that he pulls out sparingly but pointedly. And I'm pretty sure he was wearing tearaway pants.

James Kovacs: The Persistence Ignorant Domain Model

Presentation alias: The Ambassador
Underlying motif: Professorial; Wise and well-traveled
Summary: James' style is well-rounded and well-grounded. Ever the diplomat, he always manages to find good in everything. Such is the power of his pursuasion, for a fleeting moment, I considered using the ADO.NET Entity Framework.

Richard Campbell & Kent Alstad: The Scaling Habits of ASP.NET Applications

Presentation alias: The Geeks (I mean that in a good way)
Underlying motif: Dynamic, good-natured rapport;
Summary: I stayed only about fifteen minutes into this (family emergency, not content-related) so I didn't get the full Camb-stad experience. But the two feed well off each other and give a solid presentation well balanced 'twixt friendly jibes and hard-core techspeak.

Kyle the Presented

Wednesday, November 28, 2007

So I made it to Part 3. Who knew I had it in me?

For the uninitiated, I'm braindumping on my meanderings through the Timok sample application. I'd advise you to check out part 1 and part 2, partially because Part 2 includes a disclaimer that says, now that I look at it closely, don't listen to me.

So far, we've followed a request through a controller and how to apply filters to controllers. This time, we're finally going to look at some rendered code. When we left off, we had determined that unauthenticated requests to the main page, /home/index.rails, we're redirected to the Index action on the Login controller.

LoginController derives from ControllerBase, rather than SecureController. So it will not run the request through the AuthenticationFilter. Instead, the Index action executes normally. That is, it will use the default layout and the index.vm view.

So are we finally rendering something on the screen yet?

Why, yes, we are. As mentioned in part 1, the default layout will be rendered with the index.vm view in Views/Login. The HTML you see in index.vm is what is rendered on the page. Sort of. We'll take a look at it now.

OK, it kinda looks like HTML but I'm having some acid ASP flashbacks

Yeah, and it's not as pleasant as you would have hoped, right? The HTML you are looking at is littered with escape sequences that mean something to the view parser. Like classic ASP, these are processed server-side and the view engine will render appropriate HTML based on the command and its arguments.

Note that we are using NVelocity as the view engine. It is the default one provided by Monorail but is not the only one. Brail is pretty popular as is ASP.NET web forms, which has a syntax similar to what you are used to in ASP.NET. I have zero experience with either of them so in the immortal words of Handy: Read a book.

In the meantime, just assume that anything with a funky character in front, like # or $, is for NVelocity to figure out. We'll look at a couple of these next.

#capturefor(head)

The text 'twixt this and the #end block will be rendered in the page's <head> tag.

$siteroot

Generates a base URL corresponding to the base application. For example, if your application resides at http://localhost/Timok.Rbr.Portal, this URL will be substituted in place of $siteroot when the page is rendered. It is like using ~ in ASP.NET web forms.

"$UrlHelper.For("%{action='ForgotYourPassword'}")?username=" + $F('username');

This is a busy little bit of code. First is the UrlHelper which is an NVelocity construct that will create a URL for you based on the parameters passed in.In this case, it will build a URL corresponding to the ForgotYourPassword action.

$F isn't actually server-side code. It is rendered as-is in the client. $F is defined in one of MonoRail's js files (AjaxScripts.js). It is a sort of shorthand that says, "append the value of the 'username' form field to this URL when this code is executed. And since we don't know what this will be when the HTML is generated, it has to be a client-side function. It is similar to:

document.getElementById('username').value

$Form elements

These are for various form-related functions. $Form.FormTag generates the <form> tag in HTML while $Form.EndFormTag generates the </form> (along with some validation code). $Form.LabelFor and $Form.TextField generate <label> and <input type='text'> elements respectively. I'll leave it to you to figure out what $Form.PasswordField does.

#if($error)

This should be somewhat self-explanatory. The HTML in this block is rendered only if the "error" server variable is defined.

Summary

We finally got to look at some HTML even if it looked a little funny. I sorta skimmed over the funky NVelocity syntax for a few reasons:

  • It's NVelocity-specific. Brail, ASP.NET WebForms, and other view engines will have their own syntax
  • The idea should be familiar to you if you've done classic ASP development, even if the syntax is different
  • You can view the source of the resulting page just as easily as I can to see what each of these things does

From here, we'll follow through with the form submittal to see what happens when the user actually does log in.

Kyle the Moot

Sunday, November 25, 2007

Airports aren't happy places. In fact, they are pretty angry in that they are filled with angry, angry people. People who have lost their luggage, missed their connection, just had a run-in with the humorless security agents who live for any event to break up the monotony after the novelty of "guess the passenger's ailments based on the contents of the carry-on" wears off. And when one travels alone and pays attention, it can provide an endless source of entertainment.

Airplanes themselves are a little less entertaining. The people are generally in a better mood and the conversations you "overhear" are downright banal. Especially when you are leaving someplace tropical and the younger tourists are talking at a volume just slightly louder than normal so they can be sure those immediately around them can hear them talking about how drunk/sunburned/"almost" killed they got on their vacation. I cringe when I think I used to be those people (and very likely, still am).

But those are just general observations that have nothing really to do with DevTeach except that they will set the stage for the next week on this blog-thingy. Like ALT.NET, I'll be focusing more on general impressions and stories than specifics of the technology because there are people more eloquent than I who can cover details. And frankly, tech-writing is boring to write and I don't have the attention span for it most of the time.

My specific flight from NAS to YYV was fairly uneventful. Sat next to someone who was relatively chatty in the YYZ-YYV leg which doesn't bother me too much. He was apparently on his way to Vancouver to see his daughter who was having a hard time because of a recent car accident involving a drunk driver and she'd been laid off because of it and he was supposed to drive but the trailer he was going to use (which was filled with all kinds of valuable belongings including a bunch of old jazz vinyls) had been stolen and he suspected his friend's son but he couldn't tell the police because then the kid would get popped by the drug dealers he likely sold the trailer to pay off.Sheraton internet log-in page

Me: "Golly, that's a bummer....<awkward silence>....so...ummm, my name's Kyle....and....uhhhh....I'm just gonna go back and do my crossword puzzle, mmkay?"

The Sheraton Vancouver Wall Centre has made an excellent first impression being nested near both an adult store advertising 25 cent peep shows and a church that celebrates the birth of Jesus old-school: with a dazzling Christmas light display. The room will make an excellent home for the next week despite the fact that it, like all hotels in North America, comes with a coffee maker but no kettle. The only oddity is that the room seems to lack cold water. The temperature ranges from blisteringly hot from the hot tap and slightly warmer than lukewarm from the cold tap.

Internet access, I've been assured, is free, despite the ominous log-in page to the right (click for larger view) which also has another feature that's new to me in that it is very adamant that I ignore the last four fields (each helpfully labelled "Ignore this field"). So I had to wait about forty-five minutes before I could log in because my mind kept wandering back to those fields and I didn't want to break the rules this early into my stay. If they wanted me to ignore them, they shouldn't have called attention to them, instead labelling them something like "Enter your name here to receive spam from our hotel for the next four generations of your family."

'Tis all for now, hillbillies. Time to wander the streets.

Kyle the Nomadic

Friday, November 23, 2007

NHibernate is senstive to white space. Who'da thunk?

Here is the .hbm file that was causing problems:

       <generator class="foreign">
           <param name="property">
               _maker
           </param>
       </generator>

And the error message it eventually generated:

An exception of type 'NHibernate.HibernateException' occurred in NHibernate.dll but was not handled in user code
Additional information: unmapped property: OzarkInc.BanjoMakinThingy.BanjoFactory.
     _maker

I say eventually because it didn't actually give us any problems until we started saving new entities. Note that I have not formatted the message. The space 'twixt BanjoFactory and _maker appeared as above in our error messages. Which should have been my first clue as to the problem but it took a fellow hillbilly to find it. And since he's a smart'un and doesn't blog, that gives me a chance to increase my readership at his expense. (And since I know he wanders over here on occasion: Craig, consider this a formal goading to get your blog going.)

Anyway, back to my problems which is why you're all here. The simple fix:

        <generator class="foreign">
            <param name="property">_project</param>
        </generator>

So let that be a warning to you. Press Ctrl+K, Ctrl+D in your XML files at your own risk.

Kyle the Spatial

Tuesday, November 20, 2007

Jeff Atwood wrote on the spoilage of software and laments on how software seems to be doomed by the fact that people will pay for features but not bug fixes.

This is something I've thought long and hard about for the better part of a half hour over the last year or so. And every time I start up Paint.NET, I wonder, "how long, dear friend, how long?"

Here's what I would like to see more of, if you'll forgive a humble hillbilly ending statements on a preposition: Software where features are plug-ins, not reasons to upgrade. The basic application is nothing more than a shell. You want your word processor to be able to italicize text? Download the "Slanty Text" plug-in. You need to add shadow effects to your images, grab the Shadowizer plug-in. And so on and so forth.

One of the nice parts about this, assuming it can be pulled off, is that the core application needn't change often. Only when something fundamental needs fixing or adding. Or when you want to allow a whole new class of plug-ins.

This isn't to say you leave the app wide-open for third-party developers to mix and match any way they want. Yes, you allow for those types of plug-ins but for the "core" plug-ins, those are all you. You build them, you distribute them, you decide where they go in the application. Third-party plug-ins can be handled the same way these applications handle them now.

Another bonus could be in the economics. The core shell costs relatively little and each plug-in costs a couple o' bucks. And of course, you could create bundles for common plug-ins at some reduced price. This would allow people that "just want something that works" to go with a default configuration that costs something reasonable in total.

This mere theory and conjecture, mind you, despite the deep thought that went into it. It probably would work only for a certain class of operations, despite my previous example that implied Word could pull it off. And I'm sure there are a few logistical problems I haven't considered or thought through. For example, it's hard to take advantage of new UI paradigms when you are saddled with a shell you wrote five years ago (unless that is pluggable as well, I suppose).

Still, when I can type an entire blog post while waiting for an application to load up, one has to wonder...

Kyle the Patient

Friday, November 16, 2007

Today, we'll talk on the virtues of restraint, cleverly disguised as an exercise in TDD.

Here's the bug that I snagged during the stand-up: When I try to delete a Mechanical Doohicky*, I get an unhandled exception.

Careful and value-added analysis led to the following code that checks to see if the Product is being used by another object:

        public bool isPartUsed( IMechanicalDoohicky part )
        {
            foreach ( Heap heap in heaps )
            {
                if ( heap.Engine.Parts.Contains( part ) )
                {
                    return true;
                }
            }
            return false;
        }

The issue should be readily apparent. Namely, heap.Engine might be null.

My first reaction to this was: easy fix. Check heap.Engine for null and spend the rest of the hour playing Whack-A-Mole (not the version you're thinking of).

But nay, coders, let's slow down and see if there's a way we can drag this billable time out a bit in a justifiable way**.

What we're going to do first is write a test to expose this little bug. For those of you who obsess over analogies, think of it as...oh, I dunno, fixing a leak in a dam. You don't want to shut the water off, then have to turn the water on to make sure the leak is fixed. OK, maybe I'll pass on the analogies. Hillbillies are just too real. But I'm writing the test anyway because it's trendy.

Over to our test harness, we add a test that will fail specifically because of this bug:

        private bool Should_not_fail_when_checking_if_part_is_used_in_heaps_with_no_engine( )
        {
            // ... set up part and heaps with one that has no engine ...
            heaps.isPartUsed( part );
        }

Back to our code and we update it to fix the bug:

        private bool isPartUsed( IMechanicalDoohicky part )
        {
            foreach ( Heap heap in heaps )
            {
                Engine engine = heap.Engine
if ( engine != null ) { if ( engine.Parts.Contains( part ) ) { return true; } } } return false; }

So it may seem like a lot of extra work to fix a seemingly simple bug, especially because of the ominous way I commented out all the set up code in the test. But the bug is fixed and I can now prove it without having to launch the UI and going through the pain of setting up the conditions that led to it. And if anyone mucks with the implementation of Engine, we can be reasonably confident this particular bug won't get re-introduced. Plus the test acts as a sort of documentation of the bug that we've fixed.

Final note: There is a reason I stored heap.Engine in a temporary variable other than avoiding duplication.

Kyle the Exposed

* Domain objects have been renamed to protect the innocent. I.E. me

** My lawyer has advised me that, due to my increased readership in the U.S., I should add that I am officially and legally kidding.

Wednesday, November 14, 2007

I have a long-standing client who is *very* good at what he does, which is oil and gas economics. When he talks about past clients, he doesn't mention company names, he gives countries. As in, "I worked for Pakistan in the mid-70s." One day, I complained about how hot it was outside and without looking up, he said, "you don't know what hot is." I learned later he had just come back from a few months in Dubai. It was September.

This fellow doesn't have any outrageous computer needs. He uses Excel, PowerPoint, Word, and Acrobat Reader. But he's pretty specific in what these applications need to do. Especially Excel. Being an older man, he always claims that he isn't a very good example of a user because he always manages to click something that causes errors. I've always maintained that it's exactly this reason that makes him the *ideal* user. He isn't there to admire the software, he just wants it to do what he wants. Sure, he has little idiosyncracies, like pressing Ctrl+C to copy but Shift+Insert to paste but all in all, he's a very smart guy, only slightly set in his ways, and not afraid to get the latest software if it directly affects him.

He has a custom-built spreadsheet he's been using and updating for nigh on ten or fifteen years and his latest laptop came with Vista and Office 2007. The spreadsheet is over 13Mb now and it uses macros that haven't been signed. (I will listen to comments claiming it shouldn't be in Excel and nearly all will receive the same response: ClickOnce ain't got nothin' on an Excel spreadsheet when you travel eleven months out of the year.)

Forthwith are some first impressions from him:

  • Where's the File menu?
  • How do I get rid of this toolbar at the top (for presentations involving a Word document on a projector with low resolutions)?
  • I didn't get the macro security warning when I opened my spreadsheet. Do my macros still work?
  • Why the &*%$ don't my macros work anymore?
  • (In Word) This isn't Full Screen Reading in any book I've ever seen
  • (In Excel) I clicked Insert, where's the option to insert a worksheet?
  • (In Excel) How do I unhide a worksheet now that there's no Format menu?
  • What the &*%$ is with all these security messages?
  • It's funny, that *looks* like the icon to shut down the computer... 
  • Did anyone actually *use* this product before they shipped it?

The thing is, Windows XP and Office 2003 were working for him. Yes, they had minor issues and yes, we had to implement some minor workarounds but they were in exceptional situations, where we expect things not to go smoothly. Now, as he puts it, everyday things take four clicks whereas before, they took two. Perhaps it's because he's not used to the new UI paradigm but then, why does he need to do that?

In closing, a quote from the late, great Douglas Adams: "We are stuck with technology when what we really want is just stuff that works."

Kyle the Upgraded


** UPDATE **
Office 2003 is currently being installed on said user's computer. A new frustration was that his computer would tend to lock up when three or more instances of his 13Mb spreadsheet were open at a time. But the last straw was when this spreadsheet started taking in the order of minutes to save. And not just a few. I'm talking at least ten.

In case you're wondering about his laptop: brand spankin' new $3000 Dell Inspiron.

Monday, November 05, 2007

Sweet Zombie Jayzus, how is it that in the year 2007, we are forced to deal with a screen such as this?

image

In the name of all that is hillbilly, WHY CAN'T I SORT THIS LIST?!? I've had to break out the calculus books to try to figure out the algorithm used to display this monstrosity and as far as I can tell, it is proof positive that computers can in fact generate true random numbers.

For the record, I wanted to add an app.config file to my project. You don't see it here because it's listed at the bottom as Application Configuration File. Nested 'twixt VBScript File and MDI Parent.

On a side note, don't ask me how I know but I'm positive that the entry for "Database Unit Test" is going to show up in my nightmares tonight.

Kyle the Becalmed

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

Copyright © 2008 Kyle Baley. All rights reserved.
 
LATEST POSTS
 
POPULAR POSTS
 
LINKS
 
BLOG ROLL
 
CATEGORIES
 
ARCHIVE