My Secret Life as a Spaghetti Coder
home | about | contact | privacy statement | getting started with cfrails
Last week, hgs asked,
I find it interesting that lots of people write about how to produce clean code, how to do good design, taking care about language choice, interfaces, etc, but few people write about the cases where there isn't time... So, I need to know what are the forces that tell you to use a jolly good bodge?
I suspect we don't hear much about it because these other problems are often caused by that excuse. And, in the long run, taking on that technical debt will likely cause you to go so slow that that's the more interesting problem. In other words, by ignoring the need for good code, you are jumping into a downward spiral where you are giving yourself even less time (or, making it take so long to do anything that you may as well have less time). More...

Hey! Why don't you make your life easier and subscribe to the full post or short blurb RSS feed? I'm so confident you'll love my smelly pasta plate wisdom that I'm offering a no-strings-attached, lifetime money back guarantee!



This is a story about my journey as a programmer, the major highs and lows I've had along the way, and how this post came to be. It's not about how ecstasy made me a better programmer, so I apologize if that's why you came.

In any case, we'll start at the end, jump to the beginning, and move along back to today. It's long, but I hope the read is as rewarding as the write.

A while back, Reg Braithwaite challenged programing bloggers with three posts he'd love to read (and one that he wouldn't). I loved the idea so much that I've been thinking about all my experiences as a programmer off and on for the last several months, trying to find the links between what I learned from certain languages that made me a better programmer in others, and how they made me better overall. That's how this post came to be. More...


Since the gift buying season is officially upon us, I thought I'd pitch in to the rampant consumerism and list some of the toys I've had a chance to play with this year that would mean fun and learning for the programmer in your life. Plus, the thought of it sounded fun. Here they are, in no particular order other than the one in which I thought of them this morning: More...


At the O'Reilly ONLamp blog, chromatic pointed out that we should "program as if [our] maintenance programmer were not a barely-competent monkey," quoting a paragraph from Mark-Jason Dominus.

Mark was describing the idiocy of programming-by-superstition, where you might put parentheses if you are unsure of the order of operations operator precedence (or, to help barely-competent monkeys know the order precedence), rather than re-defining that order as opposed to using them to change the "normal" precedence. More...


The next few days in Houston are busy for programming technophiles. A couple of quick reminders:

BarCampHouston 2 is this Saturday, August 25, 2007 beginning at 9:00 AM at Houston Technology Center. Update: I had the map wrong since it was wrong on the BarCampHouston wiki page. I hope no one went to the wrong place. Here is the correct one: HTC. I also decided to take the day off and chill out instead of heading up there. My apologies to anyone who had planned to say hello!

HouCFUG is hosting a ColdFusion 8 release party on Tuesday, August 28 from noon to 1:00 PM at Ziggy's Healthy Grill where they'll be giving away a licensed copy of CF 8.

Finally, Agile Houston is hosting a session with Robert Martin, object mentor on Tuesday as well. It's at 6:30 PM in PGH 563 on the University of Houston Campus.

I should be at both BarCamp and at Robert's presentation, but I'll be in class during HouCFUG's meeting.


We could all stand to be better at what we do - especially those of us who write software. Although many of these ideas were not news to me, and may not be for you either, you'd be surprised at how you start to slack off and what a memory refresh will do for you.

Here are (briefly) 10 ways to improve your code from the NFJS session I attended with Neal Ford. Which do you follow? More...


Often when we make a change to some code, if it is not properly designed, the result is that cascading changes need to be done throughout the application because bugs will ripple through the system. That's one of the ideas behind why we want to have low coupling between classes. We also have unit testing to combat the effects of this, but let's just suppose we haven't written any, and haven't used JUnit Factory to create regression tests.

Given that there is a lot of code out there that isn't quite perfect, wouldn't it be nice to have a tool that could analyze changes and where they would affect other code? I can imagine how such a tool might work, but I haven't heard of one before now (that I recall, anyway).

So the point of it all: I heard something about BMC and IBM teaming up on such a tool (my understanding is that BMC started it, and IBM later joined the project). I'm assuming it'd be in Java, but does anyone have information on this? Can anyone confirm or deny the story I heard?


Peter Bell's presentation on LightWire generated some comments I found very interesting and thought provoking. (Perhaps Peter is not simply into application generation, but comment generation as well.)

The one I find most interesting is brought up by several people whose opinions I value - Joe Rinehart, Sean Corfield, Jared Rypka-Hauer, and others during and after the presentation. That is: what is the distinction between code and data, and specifically, is XML code or data (assuming there is a difference)? More...


Robert "Uncle Bob" Martin has put together a post about just what SOA is. It's very easy to understand (especially for web developers / CF programmers, since we're always talking about MVC). So if you've ever wondered "WTF is SOA?" (like me), I'd recommend giving it a read.

Demystify SOA for yourself.


This post at Worse Than Failure made its rounds today on the Yahoo pragprog group and CFCDev mailing list, and I had a response to one of the emails that I also thought was worth blogging. On pragprog, the discussion was turning into the question, "where do you draw the line on knowing when to eliminate literals?" (not a direct quote) Someone brought up the idea to use YAGNI and DRY as guiding factors: "If you need the number in just one place, just use the number there. YAGNI," and "If you find the number being repeated so that you would have to change it in several places, then externalise it so that I change in just one place is needed. DRY." More...


One of the great benefits of using a framework (in the general sense) is the freedom in portability it often gives you. Rather than writing your own Ajax routines which would need to handle browser incompatibilities, you can rely on Prototype/Scriptaculous, AjaxCFC, Spry, or a seemingly infinite number of Ajax frameworks available. We see the same phenomenon in our use of ColdFusion, which uses Java to be cross-platform. And, you can get the benefit for databases by using a framework like Transfer or Reactor or ActiveRecord in Ruby (all also have a slew of other benefits). In general, we're simply seeing an abstracting away of the differences between low-level things so we can think at a much higher level than "oh crap, what if they're using Lynx!" (Ok, I'm doubting any of those Ajax frameworks fully support Lynx =), but you get the picture) More...


Yesterday I was working on a little Java program that, when given a table, a "possible" candidate key (which could be composite), and some non-key columns would check to see if the table was in 1st, 2nd, or 3rd normal form(s). One constraint is that this program needs to be procedural in style (or rather, all of my code must reside in the file that contains the main() function).

I started out with the pseudocode programming process in psvm. My listing started to look like: More...


Our second meeting of the UH Code Dojo was just as fun as the first. This time, we decided to switch languages from Java to Ruby. And although we started quite slowly (we came unprepared and undecided on a problem and a language), we pretty much finished the anagram problem.

Now, I mentioned it was slow at first - because we were trying to decide on a problem. I'm guessing we spent about 30-45 minutes just looking over Ruby Quiz and then moving on to Pragmatic Dave's Code Kata. We learned from our experience though, and resolved to determine before-hand what we would do in the future. In any case, we finally decided on anagrams as our problem, and one of us mentioned something to the effect of "I don't know about you all, but I use Java too much at work." Of course, there's not much you can say to an argument like that - Ruby it was!

Since we found ourselves violating YAGNI at the first meeting, we decided to do a little more discussion of the problem before we started coding. One of the initial paths we explored was looping over each letter and generating every possible combination of letters, from 1 to n (n being the length of the input). We then realized that would need a variable number of nested loops, so we moved on to recursion. After that, we explored trying to use yield in conjunction with recursion, in an isolated environment. I don't recall the reasoning behind it, but whatever it was, we were starting to discover that when we passed that fork on the road a few minutes back, we took the path that led to the cannibals. (As a side note, if you're unfamiliar: yield sits in a function, which takes a closure as an argument, and runs the code in the closure -- I think that's a simple way of putting it, anyway).

After smelling the human-stew awaiting us, we backtracked a little and started looking for another idea. Enter idea number two: I'm not sure how to describe it in words, so I'll just show the code now and try to explain it afterwards:

char_count = Array.new(26).fill(0)
dictionary = ['blah', 'lab', 'timmy', 'in', 'hal', 'rude', 'open']

word = "BlAhrina".downcase

word.each_byte { |x| char_count[x - ?a] += 1 }

dictionary.each do |entry|
   char_count2 = char_count.clone
   innocent = true
   entry.each_byte do |letter|
     index = letter - ?a
     if char_count2[index] > 0
       char_count2[index] -= 1
     else
       innocent = false
       break
     end
   end
   puts entry if innocent
end

That's it: quite simple. First we initialize an array with a cell corresponding to each letter of the alphabet. Each cell holds a number, which represents the number of times that letter is used in out input, called word. These cells are set by using the line word.each_byte {...}.

Then for each entry in the dictionary, we do something similar: loop through each letter. If the total count for each letter goes to 0, we have a match (and in our case, simply print it to the standard output device). It's really a simple, elegant solution, and I think we're all glad we didn't go down the painful path of recursion. It would be fairly trivial to add a file which contained a real dictionary, and loop over that instead of each word in our array, but we didn't have one handy (nor did we happen to notice that Dave had provided one). And it would have been just an extra step on top of that to find all the anagrams in the dictionary.

I know this is just a silly little problem that you're not likely to encounter in real life, but it shows how even the simplest of problems can be tough without some thought, and I found it to be great practice. In particular, one problem we had was with trying to use TDD. Although we spent some time looking for tests we could write, and ways to test, and we even wrote an empty test thinking about what to put in there - none of us seemed to find anything to test. Now that we see the solution, it's fairly easy to figure out how to test it, but trying to drive the design with the test was proving fruitless for us. Dave alluded to this on the Kata page:
Apart from having some fun with words, this kata should make you think somewhat about algorithms. The simplest algorithms to find all the anagram combinations may take inordinate amounts of time to do the job. Working though alternatives should help bring the time down by orders of magnitude. To give you a possible point of comparison, I hacked a solution together in 25 lines of Ruby. It runs on the word list from my web site in 1.5s on a 1GHz PPC. It’s also an interesting exercise in testing: can you write unit tests to verify that your code is working correctly before setting it to work on the full dictionary.
I didn't read that before we had started (in fact, it wasn't until we had finished that anyone noticed it), but as you can tell, this exercise performed as promised. Our solution was under 25 lines, and while we didn't test it on his word list, I think our results would have been comparable (in fact, I wouldn't be surprised if we had the same basic solution he did).

Thoughts anybody?


I can't remember the last time I used anything resembling a stack or queue (other than what I'm about to blog about). Of course, I've used lists and arrays, but not with the same intent you often see in the use of a typical LIFO or FIFO mechanism. I did have occasion to use the concept in the last couple of updates to cfrails, however, so I thought I'd bring it up in case anyone else came across the same use as I have. Let me explain how I arrived at the need (which also doubles as a little documentation):

Using cfrails, to make a model you simply go into your project and create a CFC that extends cfrails.model in the model folder. Assuming that file has the same name as a table in your database, you've now got an object (after it is instantiated, of course) with all the basic CRUD methods. The case is similar for the view or controller, where you'd be in the appropriate directory, but name it modelname_view.cfc or modelname_controller.cfc. There is a way to change the name of the table if you don't want the model name to match the table for some reason, but I'll not go over it here, as it's an "undocumented feature" at the moment. More...


I'm in the middle of reading Steve McConnell's Code Complete 2 (website, Amazon), and it is chock-full of good advice (no wonder its considered a must-read classic for software developers). There's been plenty in it I've wanted to share and blog about, particularly the parts about design and class construction, and when I find the time, I certainly will. It just so happened that this time, my computer was already on so the barriers to blogging were low.

In any case, I'm in the chapter where he's talking about the "Pseudocode Programming Process." The idea is that you write precise pseudocode in English (or really, I suppose any human language that your audience will be reading in), and in doing so, you get a clear description of the intent behind the method. Of course, you shouldn't write a novel - the statements should be concise and to the point. He specifies that it should be written "at a low enough level that generating code from it will be automatic," but it should be written at the level of intent. Intent here means that you should talk about the meaning, not how the code will be implemented. The added bonus of course, is that you now have useful comments for your code. More...


On Monday (Jan. 29, 2007) we had our first meeting of the UH Code Dojo, and it was a lot of fun. Before we started, I was scared that I'd be standing there programming all by myself, with no input from the other members. But, my fear was immediately laid to rest. Not only did everyone participate a lot, one of the members, Matt (I didn't catch his last name), even took over the typing duties after about 45 minutes. That turned out to be a good thing - since I still can't type worth a crap on my laptop, and he was much faster than me.

Now, it had only been a couple of months since I last used Java - but it still amazes me how little time off you need to forget simple things, like "import" for "require." I found myself having several silly syntax errors for things as small as forgetting the semicolon at the end of the lines.

Overall, we started with 7 people, and had 5 for most of the meeting. We finished with four because one person had tons of homework to do. It seemed like those five of us who stayed were genuinely enjoying ourselves.

In any case, we decided to stick with the original plan of developing a tic-tac-toe game. You would think that a bunch of computer scientists could develop the whole game in the two hours we were there. But, you'd have been wrong.

I came away from the meeting learning two main points, which I think illustrate the main reasons we didn't complete the game:
  1. YAGNI is your friend
  2. Writing your tests first, and really checking them is very worthwhile
More...


We all know (or should know) that it's a good idea to keep your methods short. I've seen it recommended that they should be more than 7 ± 2 lines (Update: Although I still have seen it recommended they should be that short, I didn't mean to imply that I haven't seen other recommendations. Steve McConnell's Code Complete 2 says 50, I think, as Peter Bell alluded to in the comments below). The goal, of course, is simply to manage complexity, so as long as you've accomplished that, you're ok.

I've generally just created methods for three purposes that I can identify (in no particular order):
  • Follow the DRY Principle: Refactor common code out into one method.

  • Create an interface for a class

  • Reduce complexity: Sometimes, I see some code that is hard to understand or is a long related block (such as setDefaultVariablesScope()), so I'll put it into a method so I don't have to think about it while I'm working on something else.
More...


Looking at the code Joe Rinehart provided in this post on why it's a good idea to use XML configuration in Model-Glue, I think I would probably prefer the XML. (And that's saying something!)

But, I also think that the code as it stands could be better abstracted, so that the end-programmer wouldn't need to create all those objects. One strategy to abstract the complexity out of that could be to allow the programmer to just create a config object, and use that API to create other objects. I haven't thought through that idea completely, but it seems preferable to me on its face. I'm sure there are many other strategies as well.

In the comments to that post, Teddy R. Payne mentioned, "a generation script that auto generates your code and writes XML for you would seem like creating an abstraction on top of an abstraction. It seems that would introduce another layer of complexity." More...


At times, I like to push the limits of the languages I work in, just to see what I can learn. A while back, I got the idea of using structs as objects in Coldfusion, since instantiating objects is so slow. Of course, this would only be useful if you had tons of objects, and if it was substantially quicker than creating real objects. Anyway, I decided to see what I could come up with.

Unfortunately, I don't think this would be any more efficient (and possibly less), because I need to do three file operations. But, I thought I'd share what I came up with regardless.

Basically, what happens is that you tell pseudo_object.cfc what object you want to create, and it creates a fake object that behaves like a real one. It reads the CFC you tell it you want an object of. It creates a struct, finds the name of the variable you stored it in (multiple references won't matter, to my knowledge), rewrites the methods to use the scope+name of that variable, plus an extra this or variables scope to make up for variables named the same in different scopes within the CFC. Then, it attaches those methods to the struct and you now have a struct which behaves like an object. It won't work if you have any code outside of methods, however. Also, another problem may arise if you have something like this.variables.

Since I'm not entirely sure that made any sense, I'll share the code now: More...