Saturday, April 28, 2007

From Java to Ruby, Rails for Java Developers, and Everyday Scripting with Ruby

Things Every Manager Should Know (Pragmatic Programmers)

Bruce Tate is a popular Java author (Better, Faster, Lighter Java, Bitter Java and Bitter EJB) and blogger, so it's significant when he shifts his focus from Java. In the earlier Beyond Java (which I haven't read), Tate looked at what lead to Java's dominance, and the limitations that were creating opportunities for other programming languages. In From Java to Ruby: Things Every Manager Should Know (Pragmatic Programmers) Tate focuses entirely on Ruby, which he sees as a strong (but not certain) contender for the 'next' programming language (though it's unlikely that anything will be as ubiquitous as Java has been). As the title indicates, the book is targeted at managers. If you're a manager or team leader who needs an overview, perhaps because your developers are advocating Java, or you're a programmer who needs to think about about how to advocate for Ruby without your organisation this is a good book. If you're a programmer looking for details on programming in Ruby, you're better off with one of the books I talk about next.

Rails for Java Developers

If you're already familiar with web application development in Java Rails for Java Developers by Stuart Halloway and Justin Gehtland is an excellent introduction to Rails. It runs through a point by point comparison of web application development in Java (using Spring, Hibernate and JSPs) and in Ruby on Rails. It's a short, accessible book (292 pages), but it's not a replacement for Agile Web Development with Rails (Pragmatic Programmers) - if you're doing serious Rails development you'll still want that on your shelf as well. But developers who only need a comparison and an introduction, perhaps before they decide whether to jump into the deeper water, will definitely appreciate "Rails for Java Developers".

For Teams, Testers, and You

Finally, I'm reading (but haven't quite finished, because it's sitting on my desk at work as a reference)
Everyday Scripting with Ruby: For Teams, Testers, and You by Brian Marick. Although ostensibly targeted at non-programmers who need to 'get something done' with Ruby, I'm finding this to be an excellent Ruby introduction for anyone. It has the clearest explanation of regular expressions that I've come across - I'm weak on regular expressions, but after reading this book I was confident enough to apply them both willingly and successfully on my current project. Once again, this book isn't as deep as the Pickaxe book (Programming Ruby: The Pragmatic Programmers' Guide, Second Edition), but I think it's much more accessible. Definitely recommended.

Hard Facts, Dangerous Half Truths & Total Nonsense

Hard Facts, Dangerous Half-Truths And Total Nonsense: Profiting From Evidence-Based Management

Hard Facts, Dangerous Half-Truths And Total Nonsense: Profiting From Evidence-Based Management by Jeffrey Pfeffer takes aim at many of the management fads of the last 20 years - not individually, but as a group. It critiques the anecdotal approach used by many management gurus and finds it lacking. It points out that in many cases a management technique might be present in a successful company, but also present in a large number of failing companies, and many (most?) management authors only present one half of the equation.

"Hard Facts" doesn't give any easy solutions to this problem. It suggests that every company is unique, and that it's always a good idea to run some sort of internal pilot to validate a new management approach.

This isn't a great book, but you might find it very useful if you're trying to critique the management fad du jour at your company.

Wednesday, April 18, 2007

Programming is important - really important

I wrote this in response to a comment on my post about Dreaming in code, but I wanted to expose it to people who view this via RSS, so here's the comment and my response.

Finally, something I can talk about.

I disagree totally.

Programming is not about code.

For me, a program or application doesn't live in the computer. It is not the bits and bytes. It extends much, much further.

For me, an application extends across everything the code affects. Not only is it the code, but it is also the users’ and the stakeholders’ mental models, processes and understanding of what the code does, what their organisation is and how to use the code to enhance their organisation.

Applications extend beyond computers into the people.

Example - a content management system is more that just the DotNetNuke code. It is also assigning the roles of writers and editors, it is understanding the people who will read the content and shaping the navigation and tone of the articles appropriately, it is teaching everyone in the organisation that they can request changes, and communicate their important stories with the world through the web.

When I am writing an application, I am not writing code. I am talking to people, I am trying to understand their issues, ideas and viewpoints. I am trying to work my way to the root of the problem. I am working out what questions to ask, talking to end users and training people to see things in different ways.

The application exists both in the computer and in the minds of people. As application building is not about code, it's not creative writing.

You don't look at the source code for great pieces of software. Or look at the architecture of great pieces of software. You don't look at their design.

What are patterns if not examples of great pieces of software and design?

What is MSDN - the magazine? Yes it is a Microsoft advertising vehicle, but it still has great code to read, understand and appreciate.

What are all the sites, forums and blogs on coding (including this one) but a sharing of knowledge on building applications and computing?

I use some of these words differently to you. I don't think a 'program' is that same as an 'application', and I don't think that 'software/application development' is the same as 'programming' at all. So I agree with all the things you say, up to the quote, about applications and application development, but at some point in application development we need to do some programming and to me that is absolutely, positively, by definition, about code. Programming isn't the only thing that we do in application development, but it's an important thing and I think there is a tendency to devalue it; to treat it as a typing exercise in which all programs that perform the same function are treated as equally worthy (you didn't say this, but I hear it a lot). I think application development would benefit from improvements to many disciplines, but I feel that programming is one of the most neglected disciplines at all.

When we write a program we write for two very different audiences - the program needs to be understood by the computer, which is apparent when it does (or doesn't) perform the expected functions, but it also needs to be understood by human beings. Most of our effort currently goes into pleasing the computer, but in some sense this is the easier of the two audiences. Gabrielle is saying (and I agree strongly) that we need to put more of our effort into satisfying the human audience for code. I'll assert as a corollary that finding ways to make code more expressive to people will also make it easier to write code that satisfies the computer as well, but I can't offer a proof in a mathematical sense.

As to what are patterns, and the code in places like MSDN and most web sites (including this one), they bear the same relationship to great programming that a power tool catalogue has to great building. They're focussed predominantly on efficiency, and on satisfying the computer, not on the aesthetics of programming as it's experienced by a human being. Christopher Alexander presented a keynote at OOPSLA many years ago, which I had the honour of attending, at which he said that he was ashamed of the way that the software community had applied patterns; that the heart of his idea was creating environments that appealed to our humanity but that software patterns has been sterilised - stripped of aesthetics and reduced to the equivalent of screwdrivers (my words, not his, but I think I'm faithful to the intent). Show me an article, or rather not one exceptional article but a body of work, that addresses different ways to name variables within the same programming idiom to improve expressiveness, or how to write code that brings a smile to your face, and we'll be heading down the path that Gabrielle is talking about, and we'll have taken one tiny programmatic step towards Alexander's goals.

You once asked me in email why I went back to uni to study psychology - my reply should have been because I think it would make me a better application developer. If I wanted to become a better programmer I wouldn't choose psych, I'd choose creative writing and literature, and that I haven't speaks to lack of time and dedication to my craft, not to a lack of need.

Tuesday, April 17, 2007

Dreaming in Code

I've always been interested in books that tell the story if creation from the inside, and particularly when they related to software. I remember being very impressed by Tracy Kidder's The Soul Of A New Machine when I read it way back at university, and another of Kidder's works, House. This week I finished another book in the same tradition, Dreaming in Code: Two Dozen Programmers, Three Years, 4,732 Bugs, and One Quest for Transcendent Software by Scott Rosenberg.

"Dreaming in Code" recounts the development of Chandler, an open source personal information manager (PIM) that's now been in development for four years. I have to admit that when I saw the project start date, I assumed that the book documented a rise and fall, and I was really surprised to find out that the project was still in development, but without a widely used release, after all this time. It's not really important though. "Dreaming In Code" is a journey, not a destination, and it was revealing to see that developers with great pedigrees have the same problems that I do on my projects.

There were a few quotes along the way that should have been worth saving, but in the end I'm left with these:
"People write programs. That statement is worth pausing over. People write programs. Despite the field's infatuation with metaphors like architecture and bridge-building and its dabbling in alternative models from biology or physics, the act of programming today remains an act of writing - of typing character after character, word after word, line after line. Tools that let programmers create software by manipulating icons and graphics shapes on screen have a long and sometimes successful history... But these have generally served as layers of shortcuts on top of the same old text0based code, and sooner or later, to fix any really hard problems, the programmer would end up elbow-deep in that code anyway.

People write programs

...Is programming a kind of creative writing? The notion seems outlandish at first blush. Any discipline that involves complex mathematics and symbolic logic does not seem to share the same cubbyhole with poetry and self-expression. Yet the programming field could learn much from the writing world, argues Richard Gabriel, a veteran of Lisp and object-oriented programming who is now a Distinguished Engineer at Sun. 'My view is that we should train developers the way we train creative people like poets and artists. People may say, "Wall, that sounds really nuts." But what do people do when they're being trained, for example, to get a master of fine arts in poetry? They study great works of poetry. Do we do that in out software engineering disciplines? No. You don't look at the source code for great pieces of software. Or look at the architecture of great pieces of software. You don't look at their design. You don't study the lives of great software designers. So you don't study the literature of the thing you're trying to build.'"

And Rosenberg's Law:
"Software is easy to make, except when you want it to do something new"

with it's corollary,
"The only software that's worth making is software that does something new."

Friday, April 13, 2007

RCov measurements

I'm busy setting up a Rails development project at a client site, and we've chosen to use rSpec for specification/testing, and rCov to report coverage. They work quite well together, but there's one caveat - classes that aren't loaded don't appear in the coverage report at all, so for a single class there's effectively no difference between 0% coverage (no tests at all) and 100% coverage. Of course this is an oversimplification, since Ruby loads files, not classes, but it's a good enough approximation on most projects, and there's clearly some sort of problem regardless of the details.

Our solution has been to force rSpec to load everything in app/models and app/controllers before the specs are run. We do this in the rspec_helper, and since this is loaded multiple times (on different paths) it's also useful to restrict this code so it only runs once.

First, here's the code that loads the models and controllers:

class ForceLoader
["models", "controllers"].each do | app_component |
directory = File.join(RAILS_ROOT, "app/") + app_component
Dir[directory + "/**/*.rb"].each { |file| require_dependency file }

There are two things to note about this code:

  1. we use require_dependency for consistency with other Rails loading, rather than require or load;

  2. we need to ensure that the path of the file passed to require_dependency is the same as the path used by default by Rails. Ruby loading is path passed, and if you refer to the same file with two different path representations you may load it twice.

Next, let's look at the code that we put in rspec_helper.

require File.dirname(__FILE__) + '/force_loader'

If we can't reference ForceLoader we load it and run it. Once the class is loaded the rescue code won't be invoked, so this ensures once only execution.

Hopefully this approach will give you more accurate coverage reports with minimal overhead - it's certainly uncovered at least one problem on our project so far. It can also be extended to cover other parts of your app in a fairly straightforward way.

Friday, April 6, 2007

Amazon links in Ruby

As I mentioned in an earlier post, I read a lot, and I want to be able to comment on the books I like, with links to a page about the book on my preferred book seller, Amazon. I also have an associates account with Amazon and I'd like to include that in the link, even though the last time I made any money from that was about 2001! Making the links has, frankly, been a pain the butt, but I finally dusted off my Ruby and used Amazon Web Services (AWS) to make this easier.

First I tried Ruby/Amazon, but this seemed to be using an old version of the AWS and I couldn't figure out how to do an ISBN based lookup, and I eventually abandoned it. In hindsight I should have done this earlier - the functionality I need was pretty easy to write directly in Ruby, and only the latest version of AWS seems to handle both 10 and 13 digit ISBNs correctly.

So here's my code:

require 'rubygems'
require 'hpricot'
require 'open-uri'

isbn = ARGV[0]

ASSOCIATES_TAG = 'cogentconsult-20'

site = '' +
'&AWSAccessKeyId=' + ACCESS_KEY +
'&AssociateTag=' + ASSOCIATES_TAG +
'&Operation=ItemLookup' +
'&ResponseGroup=ItemAttributes,Images' +
'&IdType=ISBN' +
'&SearchIndex=Books' +
'&ItemId=' + isbn

doc = Hpricot(open(site))

author ="author").inner_html
title ="title").inner_html
detail_page ="detailpageurl").inner_html
image ="smallimage/url").inner_html

puts ''

html = "<a href='#{detail_page}'><img src='#{image}' alt='#{title}'></a><a href='#{detail_page}'>#{title}</a> by #{author}"

puts html

Open-uri made the http access a piece of cake - definitely use this instead of Net::HTTP - and Hpricot was equally adept at giving me just the parts of the returned XML that I needed.

I can run this at the command line using "ruby booklink.rb someISBN" and I get the html for both an image link and a text link, that I can then paste into my web pages and edit ass appropriate. Hopefully I'll now be less reluctant to write about the books I've read.