Author Archive

All your base are visible to us

August 9, 2011

Here’s a little safety switch for utility web pages. I have a quick-n-dirty, static html file I use simply for submitting a form to test certain features of our site. I typically use this only in my local development but occasionally in other environments. I set it by un-commenting a desired <base> element like so:

<head>
  <title>Post Test Form</title>
    <!--
    <base href="https://local.example.com/path/to/feature" />
    <base href="http://qa.example.com/path/to/feature" />
    <base href="http://production.example.com/path/to/feature" />
    -->
    <base href="http://test.example.com/path/to/feature" />
    …

This typically works well for me, but I have at times changed the ‘active’ base element and forgotten. If only the base element were rendered somewhere in the browser. I could reveal the base element with CSS (display: block), but the base element has no content, only an href attribute.

Generated content to the rescue:

    /* first reveal the 'head', hide all the head's ancestor elements, un-hide the base element */
    head {display:block;}
    head * {display: none;}
    head base {display: block;}

    /* use a pseudo-class that enables generated content */
    head base:after {
        border: 1px solid ActiveBorder;
        background-color: ActiveCaption;
        color: CaptionText;
        display: block;
        /* display the value of the href attribute */
        content: attr(href);
        padding: 1ex;
        font-family: monospace;
    }

Now, the top of my static page has a block that displays the current ‘active’ base element. While I’m at it, how about one more little tweak to warn me when I’m in production?

    head base[href="http://production.example.com/path/to/feature"]:after {
        background-color: #FEE;
        color: #F00;
        font-weight: bold;
    }

Now, my view into my base element will show bold and red if I’ve un-commented the production base element.

Advertisements

Is branching an OOP code-smell?

June 9, 2011

A code smell is a hint that something has gone wrong somewhere in your code. Use the smell to track down the problem

Kent Beck via http://c2.com/cgi/wiki?CodeSmell

I’ve developed a new code-smell sensitivity to “if.” In fact, branching in general triggers an alarm as I read through code (especially if I just typed it). 

Can something so fundamental to programming be a code smell? That gets me thinking that maybe it isn’t so fundamental to OOP.  In high academia, I was told that “structured programming” was the greatest formalism since the slicing of bread. There are 3 required pillars to structured programming:

  1. Sequence – A set of statements are executed in a certain order.
  2. Selection – Statements are executed conditionally.
  3. Iteration – A set of statements can be executed multiple times.

In light of declarative programming and OOP, all of these may be a code smell. For now, I’ll just tackle ‘selection’ and come back to the others as time permits.

Lest I wax too abstract, let’s start with some code (in pidgin java):

switch (pizza.crust) {
   case Pizza.CRUST_THICK:
      doughInOunces = 16 ;
      bakeTimeInMinutes = 13;
      break;
   case Pizza.CRUST_THIN:
      doughInOunces = 12;
      bakeTimeInMinutes = 8;
      break;
   case Pizza.CRUST_PAN;
   default:
      doughInOunces = 19;
      bakeTimeInMinutes = 18;
}

Here we have a selection, a choice if you will.  How much dough do we need and how long do we bake it? Well that depends on the thickness of the crust. Another way of saying that is that it depends on the type of pizza. That’s our first hint. First a detour through some smarter minds than mine.

I’m a big fan of the “Tell, don’t ask” principle and its close relative, “The Hollywood Principle.” Essentially, you don’t ask an object about its state and then act based on that state; you tell the object what you want it to do. In my example, the client code asks the pizza object about its state and makes a decision based on that state. That decision probably belongs near the state itself.

Here’s my proposed alternative (again in pidgin java):

class ThinCrust extends Pizza.Crust {
   int getDoughInOunces() { return 12; }
   int getBakeTimeInMinutes() { return 8; }
}
class ThickCrust extends Pizza.Crust {
   int getDoughInOunces() {return 16; }
   int getBakeTimeInMinutes() { return 13; }
}
class PanCrust extends Pizza.Crust {
   int getDoughInOunces() { return 19; }
   int getBakeTimeInMinutes() { return 18; }
}

And here’s the modified client code:

doughInOunces = pizza.crust.getDoughInOunces(); 
bakeTimeInMinutes = pizza.crust.getBakeTimeInMinutes(); 

Recall the ‘type’ hint. If you have a choice based on some type of something and you’re using a language with a type system (if not, I’d really like to hear about it), use that! In my modifications I created an inner type ‘Crust’ for the ‘Pizza’ type. Now the ‘selections’ are tucked into the types.

In the client code, I just tell the object of a certain (and probably unknown-at-compile-time) type to give me the data I need.

Okay, okay, I’m actually asking for data again. With more refactoring, my client code should actually just look like this:

pizza.bake()

The behavior that uses the values for baking time and amount of dough would still be needed, but only inside the pizza object. The pizza object itself would still want to get these values from its crust inner type, perhaps composed through an inversion of control (IoC) container like Spring.

Is there a case where one needs to perform selection instead of deferring the decision to a type? That is, what are the exceptions to my argument above?

Brainteaser++, my first crack at Ruby

February 3, 2011

I got a new desk calendar with daily brain teasers. The advertised purpose is to give my mind a little exercise for a few minutes every morning. January 5th’s puzzle inspired me. What would be better than solving this puzzle? Writing a program to solve it for me! Even better, I’ll use a new language I’ve been meaning to pick up. Now we’re flexing the brain.

Here’s the puzzle:

In the table of letters, find the two ‘lines’ that contain the same set of letters. Lines can go horizontal, vertical, or diagonal and in any direction.

M P A F H E L
C G E H O A F
F A C M T L K
E B H F M C O
G H M L E O A
A L F O G K C
H C P T A G G

This definitely lends itself to a computerized, brute-force approach. ‘Line’ and ‘in any direction’ are misdirection.  Really we’re looking for two unordered sets that contain the same elements.

The approach

  1. Read the data from stdin line-by-line and build a collection of character arrays or strings including the columns and the two diagonals.
  2. Sort each string alphabetically. Then, I can use string comparison to see if two ‘sets’ contain the same elements.
  3. Iterate over the collection of strings, looking for two that match. It will have to be an ordered collection just so that I can output an indicator of which rows, columns, or diagonals matched.

Here’s my stab at it in Ruby.

class Puzzle

  def initialize
  	# table of characters from input
  	@char_table = []
  	# the horizontal, vertical, and diagonal lines from @char_table
  	@lines = {}
  end

  def main
    readPuzzle
    buildLines
    puts findMatch or "no matches found"
  end

  private

  def readPuzzle
    while line = gets
      lineAsArray = []
      line.chomp.each_char {|c| lineAsArray << c}
      @char_table << lineAsArray
    end
  end

  def buildLines
    counter = 0

    #horizontal lines
    @char_table.each { |line|
      @lines[ counter ] = line.sort.to_s
      counter += 1
    }

    #vertical lines
    #FIXME: assumes square 2D array; ought to validate that
    for i in 0..@char_table.length() - 1
      @lines[ counter ] = []
      for j in 0..@char_table[i].length() -1
        @lines[ counter ] << @char_table[j][i]
      end
      @lines[ counter ] = @lines[ counter ].sort.to_s
      counter += 1
    end

    #diagonal lines
    @lines[ counter ] = []
    @lines[ counter + 1 ] = []
    for i in 0..@char_table.length() -1
      @lines[ counter ] << @char_table[i][i]
      @lines[ counter + 1 ] << @char_table[i][@char_table.length - i - 1 ]
    end
    @lines[ counter ] = @lines[ counter ].sort.to_s
    @lines[ counter + 1 ] = @lines[ counter + 1 ].sort.to_s
  end

  def findMatch
    until @lines.length == 0
      key, val = @lines.shift
      @lines.each{ |key2,val2|
        if val==val2 then
          return "matches found at line #{key} and line #{key2}"
        end
      }
    end
  end
end

p = Puzzle.new
p.main

I really enjoyed the exercise.  The puzzle was supposed to take about 2 minutes.  This took hours (hey, it’s my first time with Ruby, cut me some slack). However, it can solve these puzzles in well under 2 minutes, so I think I still hit the mark.

My solution is not particularly Ruby-esque.  There’s a lot of explicit iteration with indices. That may just be the nature of trying to extract strings from a two-dimensional character table. Once I got past the data-loading, things seemed to get closer to the Ruby way.

What would you improve? (Especially to all you Ruby coders on the Web, how can I make this more Ruby-like?)

Making Coldfusion sensitive to your (JSON) case

December 20, 2010

I inadvertently discovered that, contrary to popular belief and my own past experiences, ColdFusion can honor your variables’ case when using the built-in SerializeJSON.

First, the simple approach, which fails to produce most obvious results.

<cfscript>
 map = {};
 map.someNumber = 4;
 map.someString = "Hello JSON";
</cfscript>
<cfoutput>
 #SerializeJSON( map )#
<cfoutput>

This produces the following results. Notice that the keys (properties in JavaScript parlance) are UPPERCASED as though the serializer were shouting at you.

{"SOMENUMBER":4.0,"SOMESTRING":"Hello JSON"}

This becomes a problem when you deserialize the JSON in a case-sensitive context (i.e. JavaScript in a browser). It turns out this has little to do with the serialization and more to do with how ColdFusion creates struct keys from your (case-insensitive) code. We can help ColdFusion “do the right thing” by being more explicit with our keys.

Instead of creating a struct with variable names (which ColdFusion treats as case-insensitive), we’ll create struct keys with strings (which maintain their case.)

<cfscript>
 map = {};
 map[ "someNumber" ] = 4;
 map[ "someString" ] = "Hello JSON";
</cfscript>
<cfoutput>
 #SerializeJSON( map )#
</cfoutput>

This results in the following:

{"someNumber":4.0,"someString":"Hello JSON"}

Now we have no surprises when we consume this JSON in a browser. Our JavaScript object literals can use the same keys our CFML struct literals did.

Automated testing and dynamic ID’s

May 5, 2010

First off, if you’ve never used the testing tools Selenium or WebTest, you should give them a try.  Each of these tools is used to generate and run scripted interaction with your Web site (i.e. Web app functional testing).

As I built a regression test for a bug I found, I needed to automate selecting an option from a drop-down. Usually the test recorders handle this for me, and I give it no thought.  The catch is, the ‘id’ of the select element could be different on any given test run.  What I really needed was to choose a select element based on its label rather than its ‘id.’

Consider this (dynamically generated) HTML fragment:

<label for="arbitraryElementId">Product</label>
<select name="productX_another_arbitrary_id" id="arbitraryElementId">
   <option>foo</option>
   <option>fizzle</option>
</select>

<label for="somethingElse">Qty</label>
<select name="qtyX_another_arbitrary_id" id="somethingElse">
   <option>10</option>
   <option>20</option>
</select>

How can I locate the correct select element without referencing them by ID?

//select[@id='???']

That would work great if I knew the ID ahead of time.  That’s where the ‘for’ attribute comes in handy:

//label[text()='Product']/@for

That will get me the for attribute of the “Product” label.  Putting it all together, it looks like this:

//select[@id=//label[text()='Product']/@for]

Cygwin and SVN—friends at last

February 23, 2010

I’m kind of a CLI junky. Ironically, I prefer command line over GUI for its simplicity (that and I haven’t found a pointing device I care to use). In a Windows world, short of setting up an ssh server, this pretty much leaves me with Cygwin or PuTTYcyg (no, cmd.exe doesn’t count for anything).

The problem

When we upgraded to Subversion 1.5 (and now 1.6), I started running into problems with the new interactive conflict management. I prefer not to use it, but occasionally forget to add the --non-interactive flag to my commands.

The Dos emulator handled this just fine, but Cygwin would lock up. With PuTTYcyg, I can ctrl-C to at least get my prompt back. Then I have to svn cleanup. Sometimes this can bork your svn meta data beyond what ‘cleanup’ can fix. There are few things more frustrating than spending good development time on fixing your development environment.

The Solution

It turns out, you can disable interactive-conflicts by default by modifying your Subversion client’s config file. On Windows, this is %APPDATA%\Subversion\config (“$APPDATA/Subversion/config” for PuTTYcyg users).

Because I started with svn 1.1, the commented options in my config were outdated so I did the following to get a fresh one:

rm "$APPDATA/Subversion/config"
svn --version

Any subversion command will (re-)create a default config file.
Finally, I just uncommented the following line:

# interactive-conflicts = no

Now I can run SVN in my CLI of choice with no worries of losing time to repairing my local code check-out.

UPDATE: svn/cygwin now happily interactive

A colleague of mine suggested simply installing svn through the cygwin package management (i.e. re-run cygwin’s setup.exe). After doing so, I can interact with svn through local puttcyg just as I would through normal ssh. (Among other things, I no longer have to worry about my credentials being echoed when svn prompts me for authentication!)

User Error + QBQ → User Interface Error

November 7, 2009

About once a day, I sift through our aggregated Web server error messages.  My usual sorting goes something like “this needs to be addressed, that one is novel, this one is my personal test and can be ignored.”  Usually there’s at least one issue where my first reaction is “Oh, that’s just user error.”

One particular error kept coming up from our internal users to the point that it became a nuisance, and I cried out “Why can’t they get that right?!” Immediately, I was convicted by what I had read in QBQ: The Question Behind the Question (a must-read for the Dave Ramsey team).  That wasn’t a ‘QBQ’ question. What can I do so that my internal users will get that right? In this case, a drop-down list contained an invalid option entitled “Select an Option”   The solution was obvious, remove the invalid option and enhance the then-arcane validation message. This process can be generalized to the following:

User Error + QBQ → User Interface Error

Don’t get me wrong, some times a user behavior is just too bizarre to code around it.  (The customer isn’t always right.) Sometimes a customer just needs some education.  The point is that as the solution developer, I’m responsible (at least in part) for my end-users’ actions. It is neglect of this truth that yields the bad reputation programmers get for their people skills.

Let’s do better. The next time you’re faced with a “PEBKAC” (Problem Exists Between Keyboard And Computer) error, before you write it off as ID-10-T, consider the UI or the UX or the messaging or the training. You’ll ultimately wind up with a better product.  Who knows, maybe you’ll even create documentation.

Take that, Ticketmaster!

September 1, 2009

What’s the coolest project you’ve ever worked on? When that question was posed to me, one project immediately came to mind.

  • 2-D bar-code scanner-equipped, wireless, hand-held computers.
  • Portable wireless network that spans any arbitrary venue (including 15,000 seat arenas).
  • Online event registration and e-ticketing.
  • Three months.
  • One developer.

When I started working with Dave Ramsey’s LIVE Events team, we were manually fulfilling about 30,000 paper tickets each year.  Event attendance growth looked to out-pace our capacity to fulfill tickets.  Electronic ticketing was not merely on Dave’s wish list, it was a necessity for my department to meet growing demand.  It was, to be dramatic, the reason I was hired.  It was also due to launch in 4 fewer months than the Web team had planned!

Looming deadlines are great for killing scope-creep.  We wound up using our existing antiquated event registration system with an appendage for emailing PDFs.  I figured we could distribute e-tickets in November for a February event, with the hope that we would have a way of scanning them by the time we got there.

At break-neck pace, we researched bar codes scanners, bar code generator libraries, wireless LAN gear, and vendors to quote on all that stuff.  This was a lot like laying down train tracks while rolling at full speed.  In fact, for the first event, migrating the data from the Web systems database to the gate control database required a few command line tricks and manually stopping and starting Tomcat.

Throughout the course of the events season, much of my manual intervention was automated until I was no longer needed on the road.  During our second season, the system matured to the point where events could happen without my even knowing about it.  It has been an awesome experience to pull this off with the aid of a great team, and with the trust from leadership to architect this and plan my releases as I saw necessary and feasible.  All in all, it looks like the decision to build in house, however rapidly it had to be done, has yielded 20-25 fold compared to the cost of [utilizing some other ticketing service].

Independence Delay

July 3, 2009

W3C announced today the end of the XHTML 2 working group charter.  It has long been apparent that HTML 5 would become a reality, much to my chagrin, but I had hoped deep down that XHTML2 would not die.  You see, HTML 5 is a great tactical move to progress HTML making multimedia easier (among other things) for content authors. However, strategically, I feel this sets back the Web, particularly the semantic Web. I am disappointed, not because XHTML 2 has better features than HTML 5, but because the promotion of HTML 5 over XHTML 2 moves the Web in the wrong direction.

What’s so great about XHTML2

What’s so great about XHTML2? There are some nice cleanups, like replacing <h1-6> with a simple <h>.  The <hr> is replaced with a more semantically-named <separator>. The generalization of the href and src attributes were also pretty exciting. However, the biggest thing is decentralized extensibility. In fact, the W3C mentioned this in their FAQ regarding the end of XHTML2. The very existence of HTML 5 exemplifies why this is a big deal. Decentralized extensibility means we can create our own vocabularies independent of browser implementations.

The current state of things

As a developer, you’re stuck with the elements a user-agent implements.  With HTML, you are limited to what a consortium managed to agree upon and browser authors implemented (somewhat) consistently. The needs of content authors and the capabilities browsers have outgrown the existing centralized vocabularies of HTML 4 and XHTML 1.  HTML 5 addresses this problem with a brute force method: keep improving the centralized vocabulary, and try to keep up with the developer community.

Where we could be headed

If we currently live in the era of the Web browser, we ought to be headed toward the era of the XML browser.With XML, we have more liberty. We can create XML documents with our own vocabularies. We can even define the vocabularies through DTDs or other schemata.  We can mix and match our vocabularies with others. We can define the layout and presentation of new languages with CSS and XSL-FO. Better still, we can define what our new elements and attributes mean through RDF and its related technologies. This is the key.

Every time I mention this, I get the same question, “How would a browser know that my attribute mynamespace:foo@fetcherator is the same as html:a@href?” This is where RDF comes in. With semantic technologies, we can define our vocabularies in such a way that a browser will know.

Why can’t we head there with HTML 5?

We can. In fact, I believe we will (though perhaps more slowly now). My concern is the motivation behind the HTML enhancements in HTML 5 vs XHTML 2. XHTML 2 was a continuation of the W3C’s efforts to bring the benefits of XML into HTML, while HTML 5 seems to bring the benefits of new user agent capabilities into HTML. We need to decouple the user agent capabilities from our document vocabularies. This is true independence.

We can still do this.  The future may still be bright. I hope that we do not lose the vision as we postpone liberty for the comforts afforded by the latest iteration of a centralized HTML.

Plan your escape

March 21, 2009

URL encoding is not character/entity encoding.

This should go without saying, but I frequently see this confused by experienced developers, especially when working with dynamic/loosely typed languages.

URL encoding is for URLs (URIs to be more generic).  The only time to URL-encode a string is when it is part of a URL.  JavaScript provides encodeURI(), encodeURIComponent(), decodeURI, and decodeURIComponent().  In ColdFusion, you can use the  URLEncodedFormat() and URLDecode() functions.  PHP provides urlencode(), rawurlencode() and their decode counterparts.

Entity encoding is used for representing characters in a document that lie outside of the document character set or have a special meaning within the document.  For example In XML, &, <,>,”,and ‘ have to be encoded as entities (‘&amp;, &gt;, etc.) in the document source code.  Typically, characters outside of “low” ASCII need to be encoded as well.  In client-side code, you typically need not worry about entity-encoding. You’re working with a DOM, not document source code, so entity expansion/subsitituion has already been done.

ColdFusion is a little tricky on this one.  There is no equivalent to PHP’s htmlentities.  You basically have two options, HTMLEditFormat and XMLFormat.  The former will encode characters with special meanings, but it misses high-ASCII (and higher).  The latter will encode high-ASCII, but will not use special HTML entity names.  It’s for (the more generic) XML after all.  XMLFormat escapes characters using character entity references.

The concept applies outside of this concrete example, but this is the example that led me to channel my angst into what I hope is a helpful guide post for others.  In fact, you’ll notice that two paragraphs above, Word Press has transformed my double and single quotes to right-double and left-single quotes, respectively.  What are some other escaping/transforming pitfalls you’ve seen?