Welcome InformIT readers! You might also like to see my review of Eloquent Ruby. Enjoy!
With the popularity of my recent review of Design Patterns In Ruby and a series of questions on the ruby-talk mailinglist I’ve put together this interview with Russ Olsen. If you’re interested in the story behind the book, or Russ’s thoughts on Ruby and OO thinking, read on.
Some people say that Ruby makes people better programmers and OO thinkers. Do you agree? Why or why not?
Russ I think Ruby can help make you a better OO programmer because it is fundamentally a very simple language. The simplicity starts at the syntax level: Ruby syntax is spare but clear; most of the things that you want to say in Ruby you can say without having to worry too much about fiddling details like braces or a semicolons or required but redundant keywords. Ruby is programming syntax cut down just close enough to the bone to make the code concise without making it indecipherable. The simplicity also goes way down deep: Ruby’s system of classes and modules and instances is about as stripped down as you can get and still have a flexible language.
All this simplicity means that the programmer can concentrate on the essentials of getting the job done without being distracted by clutter and trivia. And that, I think, leads to better programming and programmers.Why are people interested in patterns in Ruby?
Russ Well, patterns are little packaged solutions to the problems that you come across when you build programs. So no matter what language you are using, you will probably be interested in how people solve problems in that language, interested in the design patterns appropriate to that language.
But of course, we also have these 23 specific design patterns, the ones from the GoF book. Why should Ruby programmers be interested in them? Mostly to see how they morph in the transition to Ruby. In writing Design Patterns In Ruby I saw this huge opportunity to explain that with Ruby we can improve on many of the patterns that were presented in Design Patterns. Now Design Patterns is a software engineering classic for some very good reasons, but it was written a long time ago. Many of the specific solutions – the patterns – presented in Design Patterns are very mid-90s C++ oriented. Many of them are not really not really appropriate to a open, dynamically typed language like Ruby. So in my book I tried to show how you might solve those original problems in a way that is appropriate to Ruby.How did you pick the patterns you covered in the book?
Russ I started by sitting down and making a list of the design patterns that I had actually seen in production code over the years. I also tried to think hard about the problem that each pattern was trying to solve. Then I went exploring the base of Ruby code out there – I think I read every line of Rails at least once, along with Rake and some lesser known, but really stellar projects like runt. I tried to find the code in those programs that grappled with the problems that the GoF patterns solved.
Turns out that if you go looking for them in real Ruby code, the GoF patterns fall neatly into three classes. First there are the patterns that are relatively unchanged: a builder in Ruby looks pretty much like a builder in Java and a singleton in Ruby works pretty much like a singleton in Java – though in Ruby you can get the singleton job done with just a couple of lines of code.
Second, there were the patterns that morphed to a greater or lesser degree as they passed into Ruby. There were a lot of these: iterators, proxies, decorators, adapters, commands and strategies all come to mind.
The third category was possibly the most interesting: these are the patterns that are common in other programming languages but simply do not get much use in Ruby. For example, if you go trawling for either of the classic GoF factory patterns in the Ruby code base you are going to come up with a pretty empty net. Why are factories so common in Java and yet so rare in Ruby? Have Ruby programmers completely missed the boat? Are the Ruby folks simply ignoring the problems that the factories solve? Or have they found (cue dramatic music) a better way?You introduced three Ruby specific patterns in your book, are there more of these out there?
Russ Well, I took a look at internal Domain Specific Languages, at Metaprogramming and at Convention Over Configuration. I thought that was enough for any one book. But in terms of all of the possibilites that Ruby offers, I made a barely visible scratch in the surface.
Look at it this way: All of the programmers who are coming to Ruby from the C++/Java/C# worlds are used to programming under some pretty restrictive rules. In those more tradiional languages object behavior is completely determined by the class. Classes are fixed. There is compile time and run time and things that you can do during the one that you may not do during the other. Ruby removes all of these restrictions. With Ruby you can create an object with methods all of its own, different from those of its class. You can modify just about any Ruby class anytime. With Ruby there is no compile time and run time: it’s all just time.
But with all of this freedom comes some serious responsibility. In programming as in life, just because you can do something does not mean that you should do it. I was around when the industry adopted object-oriented programming and it took us just years and years to go from “Gee, this OO stuff is great!” to really knowing how to apply OO effectively. I suspect that the industry is in the same situation with dynamic, open languages like Ruby – many of us have seen the light, but I think we are very much in the early days of figuring out how to apply these languages effectively. I’m looking forward to seeing the results of all of that figuring out rolled up in more Ruby oriented patterns.Are there other patterns that you think deserve coverage?
Russ Absolutely. Take ActiveRecord for example: Did you know that along with being the name of the database interface included with Rails that ActiveRecord is also a design pattern identified by Martin Fowler? Not many people realize this. In the book I talk a lot about the patterns that you find inside of the Rails ActiveRecord implementation, but I didn’t really have the space to talk about the ActiveRecord pattern itself.
Another easy example is Model/View/Controller. It’s been talked to death in Java, but how about the implementations of MVC that you find in the various Ruby based web frameworks? There are also the various testing patterns that emerging from the Ruby community. I could go on and on, but let me just leave it here: We have barely begun.I loved your ‘pattern in the wild’ examples. How did you choose examples for the patterns in your book?
Russ For folks who haven’t read the book, the ‘Patterns In The Wild’ sections were where I wrote about examples of the design patterns that I found in actual Ruby applications and libraries. Researching the ‘Patterns In The Wild’ was probably the most fun I had in writing the book: Imagine that your job is to go out and find the most interesting, ingenious examples of code that you possibly can.
Mostly I found the examples by simply keeping my eyes open; as I said, early on in the book I was spending a lot of time reading Ruby code and I would just note down things that caught my eye.With your ‘Design Patterns In Ruby’ and the forthcoming Ruby rewrite of ‘Refactoring’, it looks like Ruby is becoming a new language for expressing the classics. What other books do you see being rewritten in/for Ruby?
Russ I am very much an old school programmer and so the books that I would like to see updated are equally old school. I would really like see the Ruby equivalent of Knuth’s Art of Computer Programming. Volume 2 of this massive tome has been my constant companion for decades – I think that sometimes my wife is a little jealous of Mr. Knuth.
The other book that I would like to see updated into Ruby is the The Mythical Man-Month by Fred Brooks. Doing this translation would be easy because there is virtually no code in the book! Brooks was writing about problems of building software in the late 1960’s, about how to organize technical people to work well together. I think that the book is still instructive because it shows that no matter how much technical progress we make – and I certainly think that languages like Ruby represent real progress – there is a human factor in software engineering that hasn’t changed a bit.Why did you include an introductory chapter on Ruby in a book an advanced book on Ruby programming?
Russ The reason that I included the introductory chapter about Ruby in there was to make the book accessible to folks with little or no Ruby background. Now honestly, I don’t think that you could come to my book with no background in Ruby and walk away from it an expert Ruby programmer – it’s not really that kind of introductory book. But I do think that someone with experience in other languages could read my book and come away knowing about Ruby, understanding what all the shouting is about.
I also think there is a deeper point here. I’ve gotten a fair amount of feedback from the Ruby community that my book is an ‘advanced’ Ruby book because I talk about things like open classes, method_missing, DSLs and metaprogramming. I have to say that I think that we Ruby people need to stop describing these techniques as ‘advanced’: all we are doing is scaring people. We need to shout out to the world our little secret: we only use those scary sounding ‘advanced’ techniques because they make our lives easier. We use them because we are a bunch of lazy sods (as all good programmers are) and they let us write programs that work, with less effort.
Take metaprogramming for example: It’s not easy to write that first metaprogramming program. Metaprogramming is one of those techiques that you need to work at when you first try it. Well my son is studying algebra and he occasionally has trouble wrapping his head around ideas like simultaneous equations or open intervals, but that doesn’t make algebra advanced mathematics. Fundimentally the concept of metaprogramming is really quite simple: In order to solve the problem at hand, your program modifies itself at runtime. Anyone who can write code at the keyboard can learn to write programs that write code at runtime. It’s just not that complex. Writing guidance software for a Mars probe, now that’s advanced programming. Metaprograming, not so much.
This is important because there are a lot of programmers out there who are massively frustrated with trying to solve problems with the traditional programming languages and are looking for an alternative. I think we Ruby folks have a professional responsibility to shout out, “Hey, for many of your problems there is an easier way.” Now that easier way involves some programming techniques that seem strange in the beginning, but once you get used to them they stop being so strange and all you are left with is easier.