Where Are The Wise Men?

Mike's Ramblings

Uncle Bob on Dependency Injection

| Comments

This post is really just a rehash of my internal email response to my co-workers on [this article on Dependency Injection][] by Robert "Uncle Bob" Martin. I like Uncle Bob -- a lot. Just reading a couple chapters from his book Clean Code changed the way I think about programming. It had an immediate effect on how I think about code and making a stance on leaving it a little better than I found it. This also means that I know how Uncle Bob thinks, to a certain extent. And I know that Uncle Bob has strong opinions. And now I know he has strong opinions about dependency injection -- or, rather, dependency injection frameworks.

I think what he's saying in a round-about way is that the dependency injection framework should not be a deep dependency in our code. I agree with it in theory, but it's not necessarily great in practice.

Sort of like the log4j example inClean Code, Uncle Bob thinks it is good to hide the fact that we are using a library into the inner bowels of the project. In the log4j example, Uncle Bob makes his own wrapper around the log4j calls and uses his wrapper instead of calling log4j in his code. His idea is that, if they decide to change logging mechanisms, they just have to change one class. I think "why not just use [commons-logging][], since that is what is was designed for?"

Anyway, I think a Dependency Injection framework is much harder to abstract because your main method has to know about it just to get the abstract this stuff out, so it dirties up my code. I don't like it!!" I'm not sure like it either but it's a cost thing. If you decide to do dependency injection, then you have a hard dependency on that library. Sort of a contradiction in terms, certainly, but then you only have one hard dependency and the framework should take care of the rest.

Of course, Uncle Bob doesn't seem to talk about cost -- for him, it's black and white. For me, I figure you have to know what you are getting into before you start down this road. This is a good example of "What if I decide to use a Dependency Injection Framework? What are the costs?". His post is a good example of what those costs are. In that light, it can been read like [Ted Neward's infamous The Vietnam of Computer Science.][] It's OK to choose a framework for dependency injection, just know what you are getting into before you start and be ready to suffer some pain down the road.

Zsh Completion Magic

| Comments

I'm a happy user of [zsh][]for a few years now and, while I don't know all the subtleties of it, I find it a indispensable tool. People I know and respect keep asking me "Why not bash?" One of the big reasons is [zsh's completion system.][]

Bash has a add-on version of this, called [bash-completion][], and I used that before moving over to zsh full-time. Bash-completion feels, well, added on and slow and not always working. Zsh's completion, however, keeps surprising me on how much it does do. As they say, a picture is worth a thousand words.

[caption id="attachment_722" align="aligncenter" width="300" caption="I typed "./manage.py TAB" and Zsh gave me all the arguments of a standard Django manage script."][![ZSH doing Django Completion][]][][/caption]

The above screenshot came with no configuration -- I didn't have to tell zsh about Django because, well, [someone already did][]. And I'm glad for it.

It's not just for Django, either. See what happened when I did "./configure " in PHP's source tree:

[caption id="attachment_724" align="aligncenter" width="300" caption="The top part is what I got when I did "./configure TAB". The part below my prompt is what I got when I did "./configure --with-TAB""][![Zsh when configuring soruce][]][][/caption]

So note that zsh helps me figure out the right options. What I want to know the exact options for MySQL?

[caption id="attachment_725" align="aligncenter" width="300" caption="Results of ./configure --with-mTAB"][![Results of ./configure --with-mTAB][]][][/caption]

Again, none of this stuff had to be configured -- I just told zsh I wanted completion and it gave it to me. I didn't have to tell it that this was a configure script -- it knew that! Just like it knew about the Django script.

This is just a taste. I hope you bite into zsh for more goodness.

"ZSH doing Django Completion"
"Zsh when configuring soruce"
"Results of ./configure --with-mTAB"

Cleaning Up With Hazel

| Comments

Anyone who knows me well knows that I'm not a neat-freak. If you know me well enough, you know that I can be an out-right slob. My wife has tried to train me in other ways, and it's sorta worked. But I still leave things laying around that need to be dealt with -- including things that should go straight to the trash.

I'm that way with files on my computers as well. I let files sit around long after I need them and then, surprise!, I have a problem with hard drive space. I end up having to scramble to find files to delete, and end up finding ISO images and tarballs of forgotten installs that I could have delete months, sometimes years go.

After [my clean install of Snow Leopard,][] I vowed I would be better at cleaning up after myself. I would delete files that I know longer needed, remove those MP3 files after I import them into iTunes, and empty my Trash periodicially. But, really, who am I fooling? I'm not going to do daily or weekly sweeps of my hard drive seeing these things. That's where [Hazel][]stepped into my life and made things much easier.

Hazel cleans up after you. Essentially, you tell it where to look, what to look for, and what do to. Want to import MP3 files automatically into iTunes? It will do that. Want to delete files that were downloaded more than a week ago? It will do that. Delete the Trash every month? Yep. Oh, and if the Trash bin gets large, it will delete it automatically -- but only if you tell it to. What if you want to do something weird with the file? Well, you can write an AppleScript or a shell script to handle that. And you tell it all this in a nice, mostly-intutive GUI. (Click on the Screenshots link [on the main Hazel page][Hazel] for an idea.)

And added bonus is that it can delete application files when you delete the application. What's that? You thought OSX did that for you when you moved an app from the Application folder to the Trash? Well, look in your user's Library->Preferences or Library->Application Support folder. Yeah, you see a lot of folders there for applications you no longer have installed. If you had Hazel installed, it would see that you have moved an Application to the Trash and it will ask you if you want to delete the user-level files as well.

I think Hazel is an application that every Mac owner should have. So, really, [at least try it out.][Hazel] Now. Go. It's worth far more than it's $21.95 price tag.

Build a Path for Elementtree Namespaces

| Comments

I really like using [ElementTree][]and it's [lxml][]and [xml.etree][] brethern. But one of my pet peeves is[how it deals with namespaces.][]I understand the reasoning -- it's just difficult and bulky. Combining the syntax of {namespace-uri} with [an XPath-like search string][]can be confusing.

I'm muddling over this while I'm writing yet another utility script to help me with some XML. I stop and decided I'm going to build a help class, wittingly called PathBuilder.

class PathBuilder:

def __init__(self,namespace_uri):

self._template=string.Template("{%s}$tag" %namespace_uri)

return "//"+self._template.substitute(tag=tag)

return ".//"+self._template.substitute(tag=tag)

def children(self,tag):

return self._template.substitute(tag=tag)


My methods above are all that I need at this point, but you can see how to build them all. I can put all my path building knowledge in that class and then just tell it what I want and it will give it to me.

Weight Watchers Mulligatawny

| Comments

I know -- I haven't had a recipe or talked about cooking for a long time. But this may make up for it -- Mulligatawny, but the Weight Watcher's version. One cup is one serving. We doubled this and will freeze the rest.

Weight Watchers Mulligatawny


  1. 2 T Canola oil
  2. 1 onion, finely chopped
  3. 1 carrot, chopped
  4. 1 celery stalk, chopped
  5. 1/2 green bell pepper, seeded and chopped
  6. 1 tart apple, peeled, cored, and chopped
  7. 1/4 cup all purpose flour
  8. 2 t curry power
  9. 1/8 t ground mace or nutmeg
  10. 1 whole clove
  11. 2 cups chicken broth
  12. 1 tomato, peeled, seeded and chopped
  13. 1 t lemon juice
  14. 1 1/2 cups diced cooked chicken breast
  15. 1/4 t salt


saucepan over medium heat, heat the oil. Saute the onion, carrot, celery, bell pepper, and apple until softened, about 5 minutes. Stir in the flour, curry, mace, and clove; cook, stirring 1 minute. Gradually stir in the stock. Add the tomato and lemon juice; bring to a boil, stirring occasionally. Reduce the heat and simmer, covered, stirring occasionally, 30 minutes. Put a stick blender in the soup and puree the chunks of carrot and apple that are left. Add the chicken and salt, heat to serving temperature.

Search, share, and cook your recipes on Mac OS X with [SousChef][]!