[Note: this article was mostly written some weeks ago; I left it in my
"to be edited" box and then promptly forgot about it. So any and all
temporal references are way out of whack. Since originally writing this
article, I have commenced an incremental rewrite of an in-house business
management application from crazy-PHP (a common -- some may say
overwhelmingly so -- dialect of the language noted for it's complete lack
of any sort of good software development practices, such as the creation
and use of functions (!)) into Rails. Articles on this effort will be
appearing presently.]
Almost immediately after I'd finished writing my previous discussion on
why rewriting
software is evil, I decided to make a little experiment. What I did
was take a fairly well factored PHP application, and rewite (a portion of)
it in Rails.
My intent in this was not to produce a production-quality rewrite. I have
no interest in proliferating yet more functionally equivalent clones on the
world. Instead, I undertook the work simply to get a feel for (a) writing
a whole, traditional, Rails app in a short space of time, (b) how quick
Rails really was to produce an application, and (c) whether wholesale
rewrites really are as boring and life-sucking as I imagined them to be.
My methodology was this: with a small amount of knowledge of the target
application (
SysCP), the existing
database schema and templates, and a weekend, rewrite as much of SysCP as I
could in a close-as-possible reproduction of critical SysCP functionality.
My summary results are: rewrites are as boring as I thought they would be,
Rails is powerful but fairly complex and slightly buggy when you get down
into it (especially if you're working from an existing -- possibly
suboptimal -- database schema), but overall, Rails is Way Good Stuff.
On the boredom aspect -- I had two days to write code. I had some domestic
duties to attend to (walk the dog, visit the hardware store, help my wife
with attaching a new bag rack to her bike, mow the lawn, etc) but on the
whole, it was dedicated to programming. I've spent whole days (hell, 40
hour marathon stretches) cutting code before. I
knew this wasn't
a six-month deathmarch, but only a weekend experiment. Despite that, I
feel that my motivation levels were lower than they normally are when
coding. I can only imagine what it must feel like, two weeks into several
months of hard core coding, knowing that you'll end up with what you had
before, functionally speaking.
If you
are going to do the rewrite thing (and may the Flying
Spaghetti Monster have mercy on your soul if you do), then pick the right
project. SysCP is large masses of tangled PHP (is there any other kind?)
but it has a fair amount of local and global structure once you get down to
it -- for instance, it's quite well factored into business logic and
display, and the code is broken down fairly logically by action handler, so
you get entire source files that look like this:
if ($action == 'edit')
// 150 lines of twisty passage PHP
else if ($action == 'new')
// Another 150 lines
// repeat for another few actions
and so on. The nice thing about this is that, if you have to look for how
something works, you can almost certainly find it in one place in the
source. Deciphering it might be another matter, but at least you've got
something to start from.
As I mentioned, the display in SysCP is pretty nicely split off from the
logic -- a large number of templates, with common header/footer files, with
some small parts in common templatettes. Some HTML is still generated
within the actions, but due to the above action-based structure, it's
usually fairly easy to identify all of the HTML that will be associated
with a particular action and turn it into a coherent Rails template.
I would dread doing a rewrite of the presentation layer of, say,
IRM. It's idea of well-factored presentation
is to separate
print statements from logic by a blank line. To my
great shame, I've had the reins of IRM for a year, and it's still this bad.
I claim it's because I hate HTML coding with a vengeance, but I think I'm
actually just scared to try and tame that particular monster. (Update:
Martin Stevens has been doing some good work turning IRM's HTML into
Savant templates. The only
downside is that I can hear his manic laughter -- caused by IRM's insanity
slowly infecting him -- all the way from England, and it's keeping me awake
at night).
I also had to re-learn that most hated but most important of lessons --
that, no matter how much reading you may have done, until you've cut chunks
of code in a language or environment, you have no idea how it actually
behaves in your brain. Specifically, I spent a fair amount of my alloted
rewrite time learning a few little lessons in how Rails actually behaves,
and all of it's cool little features. Of course, everyone is going to have
this pain, and I've suffered it in every language that I've done any
appreciable amount of programming in, but it's always a shock to the system
that -- after all this time programming -- a new language still makes my
brane tingle curiously for a while. Luckily, I'd read and digested all of
both the Pickaxe (
Programming
Ruby) and AWDWR (
Agile Web
Development with Rails) so I knew what was possible, I just usually
wasn't sure how exactly, so I spent a lot of time with my head in the
books.
Rails' little foibles also bit me in the bum more than once. For example,
I spent over an hour (a no foolin'
hour) trying to hunt down what
I was doing stupid in my code to make Rails completely forget about the
value of a couple of my fields. The answer turned out to be to restart
Webrick (Rails' internal webserver for development testing), and the
problem cleared right up. You could hear my screams of anguish from the
moon (even through the vacuum of space -- it was a
lot of anguish).
Rails isn't the Final And Ultimate Solution To The Webapp Problem, but it's
a good start. There is near-zero administrative bumf when you're writing a
Rails app. Rails is fairly intelligent about working out what you want
done from the world around it. Code generators (which produces sensible,
minimalist templates -- not the ugly, unmaintainable behemoths produced by
Visigoth Studio, which has given the whole code generation world a bad
name) handle a lot of the low-level "oh bugger, I have to add a new file"
feeling. It's very, very anal about project structure, but (in contrast to
many other bondage-and-discipline frameworks I've looked at in the past)
this structure seems almost comforting (maybe I'm just getting old and
turning into a
satisficer).
What all this means is that you (a) don't write much code unless it moves
you toward your goal, and (b) Common structure means that any Rails app
will be fairly familiar to an incoming programmer. Unfortunately it also
means that cunning wankers will, sooner or later, work out a whole pile of
ugly tricks and contortions to get themselves out of Rails'
comfortable-but-no-doubt-incompatible-with-many-people's-ways-of-thinking
straitjacket, which I will (sooner or later) end up maintaining. Like many
of Rails' (and Ruby's) features, though, I don't see them being any more
abusable than most features of any programming language or environment --
and at least they're powerful and useful (unlike, say,
register_globals,
magic_quotes_gpc, magic
single-character variables, mandatory indenting, or banning tabs as indent
characters -- I thought I'd spread the slagging amongst lots of languages).
Productivity-wise, although I was only just kicking off my Rails webapp
knowledge, I felt I was doing fairly well. From experience, what I
produced in my weekend was roughly on par with what I could produce in PHP
in the same amount of time, had the situation been reversed. Considering
that I have about 3 weeks of Ruby/Rails knowledge, and about 5 years of PHP
experience, I think that's a big win. (Update: I've since produced a DNS
management applet for work in about 6 hours billable time, and a virtual
mail account application in about 12 hours, both using Rails. There isn't
a hope in hell that I could have performed a similar feat in PHP,
especially with the same amount of inherent flexibility that the Rails
solutions contain).
Overall, my impression of wholesale rewrites as being soul-sucking
experiences stands. I suggest they be approached with the greatest of
care, and only be permitted after an appropriate period of psychological
counselling. There is plenty of code that
needs rewriting (but
why do I always have to find it?) but replacing it by doing an
rm
-rf on the source tree and starting again is
not the answer.